summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcvs2svn <cvs2svn>2005-02-06 13:15:22 +0000
committercvs2svn <cvs2svn>2005-02-06 13:15:22 +0000
commitafcff52ef7256809a89a48347c7185644f56bb25 (patch)
treeae2eb4632cc8ebe68f337a6b3b0c7faa6b8721f0
parentfc0a2da735e00434f5e15f7cea6ec20da9e629f5 (diff)
parentde4ab1e6290d23bf8732f7ad65f5471d94e2dd3d (diff)
downloadopenssl-new-afcff52ef7256809a89a48347c7185644f56bb25.tar.gz
This commit was manufactured by cvs2svn to create branch 'BRANCH_VMS_64BIT'.
-rw-r--r--certs/demo/ca-cert.pem33
-rw-r--r--certs/demo/dsa-ca.pem43
-rw-r--r--certs/demo/dsa-pca.pem49
-rw-r--r--certs/demo/nortelCA.pem16
-rw-r--r--certs/demo/pca-cert.pem33
-rw-r--r--certs/demo/timCA.pem16
-rw-r--r--certs/demo/tjhCA.pem15
-rw-r--r--certs/demo/vsigntca.pem18
-rw-r--r--certs/expired/RegTP-4R.pem19
-rw-r--r--certs/expired/factory.pem15
-rw-r--r--certs/expired/rsa-cca.pem19
-rw-r--r--certs/expired/vsign2.pem18
-rw-r--r--certs/wellsfgo.pem23
-rwxr-xr-xcrypto/aes/asm/aes-586.pl1798
-rw-r--r--crypto/amd64cpuid.pl139
-rw-r--r--crypto/engine/eng_padlock.c1091
-rw-r--r--crypto/ia64cpuid.S9
-rw-r--r--crypto/rc4/asm/rc4-ia64.S157
-rw-r--r--crypto/sha/asm/sha1-ia64.pl549
-rw-r--r--crypto/x509/x509_vpm.c400
-rw-r--r--crypto/x509v3/v3_pci.c313
-rw-r--r--crypto/x509v3/v3_pcia.c55
-rw-r--r--crypto/x86cpuid.pl77
-rw-r--r--doc/apps/errstr.pod39
-rw-r--r--doc/apps/x509v3_config.pod456
-rw-r--r--doc/crypto/OPENSSL_ia32cap.pod35
-rw-r--r--test/P1ss.cnf37
-rw-r--r--test/P2ss.cnf45
-rw-r--r--test/testsslproxy10
-rw-r--r--util/extract-section.pl12
-rwxr-xr-xutil/opensslwrap.sh22
-rwxr-xr-xutil/shlib_wrap.sh70
32 files changed, 5631 insertions, 0 deletions
diff --git a/certs/demo/ca-cert.pem b/certs/demo/ca-cert.pem
new file mode 100644
index 0000000000..bcba68aefa
--- /dev/null
+++ b/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/certs/demo/dsa-ca.pem b/certs/demo/dsa-ca.pem
new file mode 100644
index 0000000000..9eb08f3ddd
--- /dev/null
+++ b/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/certs/demo/dsa-pca.pem b/certs/demo/dsa-pca.pem
new file mode 100644
index 0000000000..e3641ad47e
--- /dev/null
+++ b/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/certs/demo/nortelCA.pem b/certs/demo/nortelCA.pem
new file mode 100644
index 0000000000..207f34ab3a
--- /dev/null
+++ b/certs/demo/nortelCA.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICajCCAdMCBDGA0QUwDQYJKoZIhvcNAQEEBQAwfTELMAkGA1UEBhMCQ2ExDzAN
+BgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmlsaXR5IEFjY2VwdGVkMR8w
+HQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRwwGgYDVQQDExNFbnRydXN0
+IERlbW8gV2ViIENBMB4XDTk2MDQyNjEzMzUwMVoXDTA2MDQyNjEzMzUwMVowfTEL
+MAkGA1UEBhMCQ2ExDzANBgNVBAcTBk5lcGVhbjEeMBwGA1UECxMVTm8gTGlhYmls
+aXR5IEFjY2VwdGVkMR8wHQYDVQQKExZGb3IgRGVtbyBQdXJwb3NlcyBPbmx5MRww
+GgYDVQQDExNFbnRydXN0IERlbW8gV2ViIENBMIGdMA0GCSqGSIb3DQEBAQUAA4GL
+ADCBhwKBgQCaroS7O1DA0hm4IefNYU1cx/nqOmzEnk291d1XqznDeF4wEgakbkCc
+zTKxK791yNpXG5RmngqH7cygDRTHZJ6mfCRn0wGC+AI00F2vYTGqPGRQL1N3lZT0
+YDKFC0SQeMMjFIZ1aeQigroFQnHo0VB3zWIMpNkka8PY9lxHZAmWwQIBAzANBgkq
+hkiG9w0BAQQFAAOBgQBAx0UMVA1s54lMQyXjMX5kj99FJN5itb8bK1Rk+cegPQPF
+cWO9SEWyEjjBjIkjjzAwBkaEszFsNGxemxtXvwjIm1xEUMTVlPEWTs2qnDvAUA9W
+YqhWbhH0toGT36236QAsqCZ76rbTRVSSX2BHyJwJMG2tCRv7kRJ//NIgxj3H4w==
+-----END CERTIFICATE-----
+
diff --git a/certs/demo/pca-cert.pem b/certs/demo/pca-cert.pem
new file mode 100644
index 0000000000..9d754d460d
--- /dev/null
+++ b/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/certs/demo/timCA.pem b/certs/demo/timCA.pem
new file mode 100644
index 0000000000..9c8d5bf9c6
--- /dev/null
+++ b/certs/demo/timCA.pem
@@ -0,0 +1,16 @@
+Tims test GCI CA
+
+-----BEGIN CERTIFICATE-----
+MIIB8DCCAZoCAQAwDQYJKoZIhvcNAQEEBQAwgYIxCzAJBgNVBAYTAkFVMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5
+cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2RldmVsb3BtZW50MRkwFwYDVQQDExBD
+cnlwdFNvZnQgRGV2IENBMB4XDTk3MDMyMjEzMzQwNFoXDTk4MDMyMjEzMzQwNFow
+gYIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhC
+cmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxFDASBgNVBAsTC2Rl
+dmVsb3BtZW50MRkwFwYDVQQDExBDcnlwdFNvZnQgRGV2IENBMFwwDQYJKoZIhvcN
+AQEBBQADSwAwSAJBAOAOAqogG5QwAmLhzyO4CoRnx/wVy4NZP4dxJy83O1EnL0rw
+OdsamJKvPOLHgSXo3gDu9uVyvCf/QJmZAmC5ml8CAwEAATANBgkqhkiG9w0BAQQF
+AANBADRRS/GVdd7rAqRW6SdmgLJduOU2yq3avBu99kRqbp9A/dLu6r6jU+eP4oOA
+TfdbFZtAAD2Hx9jUtY3tfdrJOb8=
+-----END CERTIFICATE-----
+
diff --git a/certs/demo/tjhCA.pem b/certs/demo/tjhCA.pem
new file mode 100644
index 0000000000..67bee1b200
--- /dev/null
+++ b/certs/demo/tjhCA.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICVjCCAgACAQAwDQYJKoZIhvcNAQEEBQAwgbUxCzAJBgNVBAYTAkFVMRMwEQYD
+VQQIEwpRdWVlbnNsYW5kMREwDwYDVQQHEwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5
+cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsTI1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9O
+IEFVVEhPUklUSUVTMTQwMgYDVQQDEytaRVJPIFZBTFVFIENBIC0gREVNT05TVFJB
+VElPTiBQVVJQT1NFUyBPTkxZMB4XDTk3MDQwMzEzMjI1NFoXDTk4MDQwMzEzMjI1
+NFowgbUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpRdWVlbnNsYW5kMREwDwYDVQQH
+EwhCcmlzYmFuZTEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxLDAqBgNVBAsT
+I1dPUlRITEVTUyBDRVJUSUZJQ0FUSU9OIEFVVEhPUklUSUVTMTQwMgYDVQQDEyta
+RVJPIFZBTFVFIENBIC0gREVNT05TVFJBVElPTiBQVVJQT1NFUyBPTkxZMFwwDQYJ
+KoZIhvcNAQEBBQADSwAwSAJBAOZ7T7yqP/tyspcko3yPY1y0Cm2EmwNvzW4QgVXR
+Fjs3HmJ4xtSpXdo6mwcGezL3Abt/aQXaxv9PU8xt+Jr0OFUCAwEAATANBgkqhkiG
+9w0BAQQFAANBAOQpYmGgyCqCy1OljgJhCqQOu627oVlHzK1L+t9vBaMfn40AVUR4
+WzQVWO31KTgi5vTK1U+3h46fgUWqQ0h+6rU=
+-----END CERTIFICATE-----
diff --git a/certs/demo/vsigntca.pem b/certs/demo/vsigntca.pem
new file mode 100644
index 0000000000..05acf76e66
--- /dev/null
+++ b/certs/demo/vsigntca.pem
@@ -0,0 +1,18 @@
+subject=/O=VeriSign, Inc/OU=www.verisign.com/repository/TestCPS Incorp. By Ref. Liab. LTD./OU=For VeriSign authorized testing only. No assurances (C)VS1997
+notBefore=Mar 4 00:00:00 1997 GMT
+notAfter=Mar 4 23:59:59 2025 GMT
+-----BEGIN CERTIFICATE-----
+MIICTTCCAfcCEEdoCqpuXxnoK27q7d58Qc4wDQYJKoZIhvcNAQEEBQAwgakxFjAU
+BgNVBAoTDVZlcmlTaWduLCBJbmMxRzBFBgNVBAsTPnd3dy52ZXJpc2lnbi5jb20v
+cmVwb3NpdG9yeS9UZXN0Q1BTIEluY29ycC4gQnkgUmVmLiBMaWFiLiBMVEQuMUYw
+RAYDVQQLEz1Gb3IgVmVyaVNpZ24gYXV0aG9yaXplZCB0ZXN0aW5nIG9ubHkuIE5v
+IGFzc3VyYW5jZXMgKEMpVlMxOTk3MB4XDTk3MDMwNDAwMDAwMFoXDTI1MDMwNDIz
+NTk1OVowgakxFjAUBgNVBAoTDVZlcmlTaWduLCBJbmMxRzBFBgNVBAsTPnd3dy52
+ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9UZXN0Q1BTIEluY29ycC4gQnkgUmVmLiBM
+aWFiLiBMVEQuMUYwRAYDVQQLEz1Gb3IgVmVyaVNpZ24gYXV0aG9yaXplZCB0ZXN0
+aW5nIG9ubHkuIE5vIGFzc3VyYW5jZXMgKEMpVlMxOTk3MFwwDQYJKoZIhvcNAQEB
+BQADSwAwSAJBAMak6xImJx44jMKcbkACy5/CyMA2fqXK4PlzTtCxRq5tFkDzne7s
+cI8oFK/J+gFZNE3bjidDxf07O3JOYG9RGx8CAwEAATANBgkqhkiG9w0BAQQFAANB
+ADT523tENOKrEheZFpsJx1UUjPrG7TwYc/C4NBHrZI4gZJcKVFIfNulftVS6UMYW
+ToLEMaUojc3DuNXHG21PDG8=
+-----END CERTIFICATE-----
diff --git a/certs/expired/RegTP-4R.pem b/certs/expired/RegTP-4R.pem
new file mode 100644
index 0000000000..6f2c6abccd
--- /dev/null
+++ b/certs/expired/RegTP-4R.pem
@@ -0,0 +1,19 @@
+issuer= CN=4R-CA 1:PN+0.2.262.1.10.7.20=#130131,O=Regulierungsbeh\C3\88orde f\C3\88ur Telekommunikation und Post,C=DE
+notBefore=Jan 21 16:04:53 1999 GMT
+notAfter=Jan 21 16:04:53 2004 GMT
+subject= CN=4R-CA 1:PN+0.2.262.1.10.7.20=#130131,O=Regulierungsbeh\C3\88orde f\C3\88ur Telekommunikation und Post,C=DE
+-----BEGIN CERTIFICATE-----
+MIICZzCCAdOgAwIBAgIEOwVn1DAKBgYrJAMDAQIFADBvMQswCQYDVQQGEwJERTE9
+MDsGA1UEChQ0UmVndWxpZXJ1bmdzYmVoyG9yZGUgZsh1ciBUZWxla29tbXVuaWth
+dGlvbiB1bmQgUG9zdDEhMAwGBwKCBgEKBxQTATEwEQYDVQQDFAo0Ui1DQSAxOlBO
+MCIYDzE5OTkwMTIxMTYwNDUzWhgPMjAwNDAxMjExNjA0NTNaMG8xCzAJBgNVBAYT
+AkRFMT0wOwYDVQQKFDRSZWd1bGllcnVuZ3NiZWjIb3JkZSBmyHVyIFRlbGVrb21t
+dW5pa2F0aW9uIHVuZCBQb3N0MSEwDAYHAoIGAQoHFBMBMTARBgNVBAMUCjRSLUNB
+IDE6UE4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGAjzHbq2asUlqeWbXTQHso
+aVF6YIPVH3c/B2cbuy9HJ/lnE6x0asOzM2DGDqi47xkdAxPc0LZ0fxO87rkmz7xs
+jJObnVrMXpyUSDSp5Y0wqKJdsFdr6mGFOQZteIti8AJnr8xMkwnWVyuOlEXsFe1h
+5gxwQXrOcPinE6qu1t/3PmECBMAAAAGjEjAQMA4GA1UdDwEB/wQEAwIBBjAKBgYr
+JAMDAQIFAAOBgQA+RdocBmA2VV9E5aKPBcp01tdZAvvW9Tve3docArVKR/4/yvSX
+Z+wvzzk+uu4qBp49HN3nqPYMrzbTmjBFu4ce5fkZ7dHF0W1sSBL0rox5z36Aq2re
+JjfEOEmSnNe0+opuh4FSVOssXblXTE8lEQU0FhhItgDx2ADnWZibaxLG4w==
+-----END CERTIFICATE-----
diff --git a/certs/expired/factory.pem b/certs/expired/factory.pem
new file mode 100644
index 0000000000..8e28b391b2
--- /dev/null
+++ b/certs/expired/factory.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICTTCCAbagAwIBAgIBADANBgkqhkiG9w0BAQQFADBMMQswCQYDVQQGEwJHQjEM
+MAoGA1UEChMDVUNMMRgwFgYDVQQLEw9JQ0UtVEVMIFByb2plY3QxFTATBgNVBAMT
+DFRydXN0RmFjdG9yeTAeFw05NzA0MjIxNDM5MTRaFw05ODA0MjIxNDM5MTRaMEwx
+CzAJBgNVBAYTAkdCMQwwCgYDVQQKEwNVQ0wxGDAWBgNVBAsTD0lDRS1URUwgUHJv
+amVjdDEVMBMGA1UEAxMMVHJ1c3RGYWN0b3J5MIGcMAoGBFUIAQECAgQAA4GNADCB
+iQKBgQCEieR8NcXkUW1f0G6aC6u0i8q/98JqS6RxK5YmHIGKCkuTWAUjzLfUa4dt
+U9igGCjTuxaDqlzEim+t/02pmiBZT9HaX++35MjQPUWmsChcYU5WyzGErXi+rQaw
+zlwS73zM8qiPj/97lXYycWhgL0VaiDSPxRXEUdWoaGruom4mNQIDAQABo0IwQDAd
+BgNVHQ4EFgQUHal1LZr7oVg5z6lYzrhTgZRCmcUwDgYDVR0PAQH/BAQDAgH2MA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAfaggfl6FZoioecjv0dq8
+/DXo/u11iMZvXn08gjX/zl2b4wtPbShOSY5FhkSm8GeySasz+/Nwb/uzfnIhokWi
+lfPZHtlCWtXbIy/TN51eJyq04ceDCQDWvLC2enVg9KB+GJ34b5c5VaPRzq8MBxsA
+S7ELuYGtmYgYm9NZOIr7yU0=
+-----END CERTIFICATE-----
diff --git a/certs/expired/rsa-cca.pem b/certs/expired/rsa-cca.pem
new file mode 100644
index 0000000000..69f5c1c84c
--- /dev/null
+++ b/certs/expired/rsa-cca.pem
@@ -0,0 +1,19 @@
+subject=/C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority
+issuer= /C=US/O=RSA Data Security, Inc./OU=Commercial Certification Authority
+notBefore=941104185834Z
+notAfter =991103185834Z
+-----BEGIN X509 CERTIFICATE-----
+
+MIICIzCCAZACBQJBAAAWMA0GCSqGSIb3DQEBAgUAMFwxCzAJBgNVBAYTAlVTMSAw
+HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVy
+Y2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NDExMDQxODU4MzRaFw05
+OTExMDMxODU4MzRaMFwxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdSU0EgRGF0YSBT
+ZWN1cml0eSwgSW5jLjErMCkGA1UECxMiQ29tbWVyY2lhbCBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eTCBmzANBgkqhkiG9w0BAQEFAAOBiQAwgYUCfgCk+4Fie84QJ93o
+975sbsZwmdu41QUDaSiCnHJ/lj+O7Kwpkj+KFPhCdr69XQO5kNTQvAayUTNfxMK/
+touPmbZiImDd298ggrTKoi8tUO2UMt7gVY3UaOLgTNLNBRYulWZcYVI4HlGogqHE
+7yXpCuaLK44xZtn42f29O2nZ6wIDAQABMA0GCSqGSIb3DQEBAgUAA34AdrW2EP4j
+9/dZYkuwX5zBaLxJu7NJbyFHXSudVMQAKD+YufKKg5tgf+tQx6sFEC097TgCwaVI
+0v5loMC86qYjFmZsGySp8+x5NRhPJsjjr1BKx6cxa9B8GJ1Qv6km+iYrRpwUqbtb
+MJhCKLVLU7tDCZJAuqiqWqTGtotXTcU=
+-----END X509 CERTIFICATE-----
diff --git a/certs/expired/vsign2.pem b/certs/expired/vsign2.pem
new file mode 100644
index 0000000000..d8bdd8c812
--- /dev/null
+++ b/certs/expired/vsign2.pem
@@ -0,0 +1,18 @@
+subject=/C=US/O=VeriSign, Inc./OU=Class 2 Public Primary Certification Authority
+notBefore=Jan 29 00:00:00 1996 GMT
+notAfter=Jan 7 23:59:59 2004 GMT
+-----BEGIN CERTIFICATE-----
+MIICPTCCAaYCEQC6WslMBTuS1qe2307QU5INMA0GCSqGSIb3DQEBAgUAMF8xCzAJ
+BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh
+c3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05
+NjAxMjkwMDAwMDBaFw0wNDAxMDcyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD
+VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMiBQdWJsaWMgUHJp
+bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB
+jQAwgYkCgYEAtlqLow1qI4OAa885h/QhEzMGTCWi7VUSl8WngLn6g8EgoPovFQ18
+oWBrfnks+gYPOq72G2+x0v8vKFJfg31LxHq3+GYfgFT8t8KOWUoUV0bRmpO+QZED
+uxWAk1zr58wIbD8+s0r8/0tsI9VQgiZEGY4jw3HqGSRHBJ51v8imAB8CAwEAATAN
+BgkqhkiG9w0BAQIFAAOBgQC2AB+TV6QHp0DOZUA/VV7t7/pUSaUw1iF8YYfug5ML
+v7Qz8pisnwa/TqjOFIFMywROWMPPX+5815pvy0GKt3+BuP+EYcYnQ2UdDOyxAArd
+G6S7x3ggKLKi3TaVLuFUT79guXdoEZkj6OpS6KoATmdOu5C1RZtG644W78QzWzM9
+1Q==
+-----END CERTIFICATE-----
diff --git a/certs/wellsfgo.pem b/certs/wellsfgo.pem
new file mode 100644
index 0000000000..2ba88cdda7
--- /dev/null
+++ b/certs/wellsfgo.pem
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC
+VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v
+dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0
+MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww
+KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G
+A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13
+5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE
+SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O
+JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu
+ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE
+AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB
+AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB
+CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw
+b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo
+7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/
+0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7
+nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
+x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ
+33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
+-----END CERTIFICATE-----
diff --git a/crypto/aes/asm/aes-586.pl b/crypto/aes/asm/aes-586.pl
new file mode 100755
index 0000000000..ee02ded463
--- /dev/null
+++ b/crypto/aes/asm/aes-586.pl
@@ -0,0 +1,1798 @@
+#!/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 3.1.
+#
+# 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 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...
+#
+# 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[-3] 23[24] 22[23]
+# AMD K8 19 18
+# PIII 26 23
+# Pentium 63(*) 52
+#
+# (*) Performance difference between small footprint code and fully
+# unrolled in more commonly used CBC mode is not as big, 4% for
+# for Pentium. PIII's ~13% difference [in both cases in 3rd
+# version] is considered tolerable...
+#
+# 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. 56 "small" cycles/byte on
+# senior Pentium, because certain function prologues and epilogues are
+# effectively taken out of the loop...
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"aes-586.pl",$ARGV[$#ARGV] eq "386");
+
+$s0="eax";
+$s1="ebx";
+$s2="ecx";
+$s3="edx";
+$key="edi";
+$acc="esi";
+
+$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(0,"esp"),$s[2]); # save s2
+ &mov ($v1,$s[0]); # copy s0
+ &mov (&DWP(4,"esp"),$s[1]); # save s1
+
+ &movz ($s[2],&HB($s[0]));
+ &and ($s[0],0xFF);
+ &mov ($s[0],&DWP(1024*0,$te,$s[0],4)); # s0>>0
+ &shr ($v1,16);
+ &mov ($s[3],&DWP(1024*1,$te,$s[2],4)); # s0>>8
+ &movz ($s[1],&HB($v1));
+ &and ($v1,0xFF);
+ &mov ($s[2],&DWP(1024*2,$te,$v1,4)); # s0>>16
+ &mov ($v1,$v0);
+ &mov ($s[1],&DWP(1024*3,$te,$s[1],4)); # s0>>24
+
+ &and ($v0,0xFF);
+ &xor ($s[3],&DWP(1024*0,$te,$v0,4)); # s3>>0
+ &movz ($v0,&HB($v1));
+ &shr ($v1,16);
+ &xor ($s[2],&DWP(1024*1,$te,$v0,4)); # s3>>8
+ &movz ($v0,&HB($v1));
+ &and ($v1,0xFF);
+ &xor ($s[1],&DWP(1024*2,$te,$v1,4)); # s3>>16
+ &mov ($v1,&DWP(0,"esp")); # restore s2
+ &xor ($s[0],&DWP(1024*3,$te,$v0,4)); # s3>>24
+
+ &mov ($v0,$v1);
+ &and ($v1,0xFF);
+ &xor ($s[2],&DWP(1024*0,$te,$v1,4)); # s2>>0
+ &movz ($v1,&HB($v0));
+ &shr ($v0,16);
+ &xor ($s[1],&DWP(1024*1,$te,$v1,4)); # s2>>8
+ &movz ($v1,&HB($v0));
+ &and ($v0,0xFF);
+ &xor ($s[0],&DWP(1024*2,$te,$v0,4)); # s2>>16
+ &mov ($v0,&DWP(4,"esp")); # restore s1
+ &xor ($s[3],&DWP(1024*3,$te,$v1,4)); # s2>>24
+
+ &mov ($v1,$v0);
+ &and ($v0,0xFF);
+ &xor ($s[1],&DWP(1024*0,$te,$v0,4)); # s1>>0
+ &movz ($v0,&HB($v1));
+ &shr ($v1,16);
+ &xor ($s[0],&DWP(1024*1,$te,$v0,4)); # s1>>8
+ &movz ($v0,&HB($v1));
+ &and ($v1,0xFF);
+ &xor ($s[3],&DWP(1024*2,$te,$v1,4)); # s1>>16
+ &mov ($key,&DWP(12,"esp")); # reincarnate v1 as key
+ &xor ($s[2],&DWP(1024*3,$te,$v0,4)); # s1>>24
+}
+
+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,&DWP(12,"esp")); }##%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(1024*0,$te,$out,4));
+
+ if ($i==3) { $tmp=$s[1]; }##%eax
+ &movz ($tmp,&HB($s[1]));
+ &xor ($out,&DWP(1024*1,$te,$tmp,4));
+
+ if ($i==3) { $tmp=$s[2]; &mov ($s[1],&DWP(0,"esp")); }##%ebx
+ else { &mov ($tmp,$s[2]);
+ &shr ($tmp,16); }
+ if ($i==2) { &and ($s[1],0xFF); }#%edx[2]
+ &and ($tmp,0xFF);
+ &xor ($out,&DWP(1024*2,$te,$tmp,4));
+
+ if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(4,"esp")); }##%ecx
+ elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2]
+ else { &mov ($tmp,$s[3]);
+ &shr ($tmp,24) }
+ &xor ($out,&DWP(1024*3,$te,$tmp,4));
+ if ($i<2) { &mov (&DWP(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,&DWP(12,"esp")); }##%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(1024*4,$te,$out,4));
+ &and ($out,0x000000ff);
+
+ if ($i==3) { $tmp=$s[1]; }##%eax
+ &movz ($tmp,&HB($s[1]));
+ &mov ($tmp,&DWP(1024*4,$te,$tmp,4));
+ &and ($tmp,0x0000ff00);
+ &xor ($out,$tmp);
+
+ if ($i==3) { $tmp=$s[2]; &mov ($s[1],&DWP(0,"esp")); }##%ebx
+ else { mov ($tmp,$s[2]);
+ &shr ($tmp,16); }
+ if ($i==2) { &and ($s[1],0xFF); }#%edx[2]
+ &and ($tmp,0xFF);
+ &mov ($tmp,&DWP(1024*4,$te,$tmp,4));
+ &and ($tmp,0x00ff0000);
+ &xor ($out,$tmp);
+
+ if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(4,"esp")); }##%ecx
+ elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2]
+ else { &mov ($tmp,$s[3]);
+ &shr ($tmp,24); }
+ &mov ($tmp,&DWP(1024*4,$te,$tmp,4));
+ &and ($tmp,0xff000000);
+ &xor ($out,$tmp);
+ if ($i<2) { &mov (&DWP(4*$i,"esp"),$out); }
+ if ($i==3) { &mov ($s[3],$acc); }
+}
+
+&public_label("AES_Te");
+&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");
+ }
+
+ # allocate aligned stack frame
+ &mov ($acc,"esp");
+ &sub ("esp",20);
+ &and ("esp",-16);
+
+ &mov (&DWP(12,"esp"),$key); # save key
+ &mov (&DWP(16,"esp"),$acc); # save %esp
+
+ &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 (&DWP(8,"esp"),$acc); # end of key schedule
+ &align (4);
+ &set_label("loop");
+ if ($vertical_spin) {
+ &encvert("ebp",$s0,$s1,$s2,$s3);
+ } else {
+ &encstep(0,"ebp",$s0,$s1,$s2,$s3);
+ &encstep(1,"ebp",$s1,$s2,$s3,$s0);
+ &encstep(2,"ebp",$s2,$s3,$s0,$s1);
+ &encstep(3,"ebp",$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,&DWP(8,"esp"));
+ &mov (&DWP(12,"esp"),$key);
+ &jb (&label("loop"));
+ }
+ else {
+ &cmp ($acc,10);
+ &jle (&label("10rounds"));
+ &cmp ($acc,12);
+ &jle (&label("12rounds"));
+
+ &set_label("14rounds");
+ for ($i=1;$i<3;$i++) {
+ if ($vertical_spin) {
+ &encvert("ebp",$s0,$s1,$s2,$s3);
+ } else {
+ &encstep(0,"ebp",$s0,$s1,$s2,$s3);
+ &encstep(1,"ebp",$s1,$s2,$s3,$s0);
+ &encstep(2,"ebp",$s2,$s3,$s0,$s1);
+ &encstep(3,"ebp",$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 (&DWP(12,"esp"),$key); # advance rd_key
+ &set_label("12rounds");
+ for ($i=1;$i<3;$i++) {
+ if ($vertical_spin) {
+ &encvert("ebp",$s0,$s1,$s2,$s3);
+ } else {
+ &encstep(0,"ebp",$s0,$s1,$s2,$s3);
+ &encstep(1,"ebp",$s1,$s2,$s3,$s0);
+ &encstep(2,"ebp",$s2,$s3,$s0,$s1);
+ &encstep(3,"ebp",$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 (&DWP(12,"esp"),$key); # advance rd_key
+ &set_label("10rounds");
+ for ($i=1;$i<10;$i++) {
+ if ($vertical_spin) {
+ &encvert("ebp",$s0,$s1,$s2,$s3);
+ } else {
+ &encstep(0,"ebp",$s0,$s1,$s2,$s3);
+ &encstep(1,"ebp",$s1,$s2,$s3,$s0);
+ &encstep(2,"ebp",$s2,$s3,$s0,$s1);
+ &encstep(3,"ebp",$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,"ebp",$s0,$s1,$s2,$s3);
+ &enclast(1,"ebp",$s1,$s2,$s3,$s0);
+ &enclast(2,"ebp",$s2,$s3,$s0,$s1);
+ &enclast(3,"ebp",$s3,$s0,$s1,$s2);
+
+ &mov ("esp",&DWP(16,"esp")); # restore %esp
+ &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);
+#Te1:
+ &data_word(0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d);
+ &data_word(0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154);
+ &data_word(0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d);
+ &data_word(0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a);
+ &data_word(0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87);
+ &data_word(0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b);
+ &data_word(0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea);
+ &data_word(0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b);
+ &data_word(0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a);
+ &data_word(0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f);
+ &data_word(0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908);
+ &data_word(0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f);
+ &data_word(0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e);
+ &data_word(0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5);
+ &data_word(0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d);
+ &data_word(0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f);
+ &data_word(0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e);
+ &data_word(0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb);
+ &data_word(0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce);
+ &data_word(0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397);
+ &data_word(0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c);
+ &data_word(0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed);
+ &data_word(0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b);
+ &data_word(0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a);
+ &data_word(0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16);
+ &data_word(0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194);
+ &data_word(0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81);
+ &data_word(0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3);
+ &data_word(0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a);
+ &data_word(0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104);
+ &data_word(0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263);
+ &data_word(0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d);
+ &data_word(0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f);
+ &data_word(0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39);
+ &data_word(0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47);
+ &data_word(0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695);
+ &data_word(0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f);
+ &data_word(0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83);
+ &data_word(0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c);
+ &data_word(0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76);
+ &data_word(0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e);
+ &data_word(0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4);
+ &data_word(0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6);
+ &data_word(0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b);
+ &data_word(0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7);
+ &data_word(0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0);
+ &data_word(0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25);
+ &data_word(0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018);
+ &data_word(0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72);
+ &data_word(0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751);
+ &data_word(0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21);
+ &data_word(0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85);
+ &data_word(0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa);
+ &data_word(0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12);
+ &data_word(0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0);
+ &data_word(0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9);
+ &data_word(0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233);
+ &data_word(0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7);
+ &data_word(0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920);
+ &data_word(0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a);
+ &data_word(0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17);
+ &data_word(0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8);
+ &data_word(0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11);
+ &data_word(0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a);
+#Te2:
+ &data_word(0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b);
+ &data_word(0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5);
+ &data_word(0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b);
+ &data_word(0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76);
+ &data_word(0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d);
+ &data_word(0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0);
+ &data_word(0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf);
+ &data_word(0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0);
+ &data_word(0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26);
+ &data_word(0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc);
+ &data_word(0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1);
+ &data_word(0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15);
+ &data_word(0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3);
+ &data_word(0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a);
+ &data_word(0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2);
+ &data_word(0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75);
+ &data_word(0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a);
+ &data_word(0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0);
+ &data_word(0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3);
+ &data_word(0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784);
+ &data_word(0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced);
+ &data_word(0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b);
+ &data_word(0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39);
+ &data_word(0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf);
+ &data_word(0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb);
+ &data_word(0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485);
+ &data_word(0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f);
+ &data_word(0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8);
+ &data_word(0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f);
+ &data_word(0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5);
+ &data_word(0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321);
+ &data_word(0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2);
+ &data_word(0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec);
+ &data_word(0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917);
+ &data_word(0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d);
+ &data_word(0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573);
+ &data_word(0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc);
+ &data_word(0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388);
+ &data_word(0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14);
+ &data_word(0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db);
+ &data_word(0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a);
+ &data_word(0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c);
+ &data_word(0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662);
+ &data_word(0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79);
+ &data_word(0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d);
+ &data_word(0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9);
+ &data_word(0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea);
+ &data_word(0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808);
+ &data_word(0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e);
+ &data_word(0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6);
+ &data_word(0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f);
+ &data_word(0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a);
+ &data_word(0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66);
+ &data_word(0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e);
+ &data_word(0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9);
+ &data_word(0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e);
+ &data_word(0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311);
+ &data_word(0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794);
+ &data_word(0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9);
+ &data_word(0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf);
+ &data_word(0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d);
+ &data_word(0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868);
+ &data_word(0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f);
+ &data_word(0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16);
+#Te3:
+ &data_word(0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b);
+ &data_word(0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5);
+ &data_word(0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b);
+ &data_word(0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676);
+ &data_word(0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d);
+ &data_word(0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0);
+ &data_word(0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf);
+ &data_word(0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0);
+ &data_word(0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626);
+ &data_word(0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc);
+ &data_word(0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1);
+ &data_word(0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515);
+ &data_word(0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3);
+ &data_word(0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a);
+ &data_word(0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2);
+ &data_word(0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575);
+ &data_word(0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a);
+ &data_word(0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0);
+ &data_word(0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3);
+ &data_word(0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484);
+ &data_word(0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded);
+ &data_word(0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b);
+ &data_word(0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939);
+ &data_word(0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf);
+ &data_word(0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb);
+ &data_word(0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585);
+ &data_word(0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f);
+ &data_word(0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8);
+ &data_word(0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f);
+ &data_word(0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5);
+ &data_word(0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121);
+ &data_word(0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2);
+ &data_word(0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec);
+ &data_word(0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717);
+ &data_word(0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d);
+ &data_word(0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373);
+ &data_word(0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc);
+ &data_word(0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888);
+ &data_word(0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414);
+ &data_word(0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb);
+ &data_word(0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a);
+ &data_word(0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c);
+ &data_word(0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262);
+ &data_word(0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979);
+ &data_word(0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d);
+ &data_word(0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9);
+ &data_word(0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea);
+ &data_word(0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808);
+ &data_word(0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e);
+ &data_word(0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6);
+ &data_word(0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f);
+ &data_word(0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a);
+ &data_word(0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666);
+ &data_word(0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e);
+ &data_word(0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9);
+ &data_word(0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e);
+ &data_word(0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111);
+ &data_word(0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494);
+ &data_word(0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9);
+ &data_word(0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf);
+ &data_word(0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d);
+ &data_word(0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868);
+ &data_word(0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f);
+ &data_word(0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616);
+#Te4:
+ &data_word(0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b);
+ &data_word(0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5);
+ &data_word(0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b);
+ &data_word(0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676);
+ &data_word(0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d);
+ &data_word(0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0);
+ &data_word(0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf);
+ &data_word(0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0);
+ &data_word(0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626);
+ &data_word(0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc);
+ &data_word(0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1);
+ &data_word(0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515);
+ &data_word(0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3);
+ &data_word(0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a);
+ &data_word(0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2);
+ &data_word(0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575);
+ &data_word(0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a);
+ &data_word(0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0);
+ &data_word(0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3);
+ &data_word(0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484);
+ &data_word(0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed);
+ &data_word(0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b);
+ &data_word(0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939);
+ &data_word(0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf);
+ &data_word(0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb);
+ &data_word(0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585);
+ &data_word(0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f);
+ &data_word(0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8);
+ &data_word(0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f);
+ &data_word(0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5);
+ &data_word(0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121);
+ &data_word(0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2);
+ &data_word(0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec);
+ &data_word(0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717);
+ &data_word(0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d);
+ &data_word(0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373);
+ &data_word(0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc);
+ &data_word(0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888);
+ &data_word(0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414);
+ &data_word(0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb);
+ &data_word(0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a);
+ &data_word(0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c);
+ &data_word(0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262);
+ &data_word(0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979);
+ &data_word(0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d);
+ &data_word(0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9);
+ &data_word(0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea);
+ &data_word(0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808);
+ &data_word(0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e);
+ &data_word(0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6);
+ &data_word(0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f);
+ &data_word(0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a);
+ &data_word(0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666);
+ &data_word(0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e);
+ &data_word(0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9);
+ &data_word(0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e);
+ &data_word(0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111);
+ &data_word(0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494);
+ &data_word(0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9);
+ &data_word(0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf);
+ &data_word(0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d);
+ &data_word(0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868);
+ &data_word(0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f);
+ &data_word(0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616);
+#rcon:
+ &data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008);
+ &data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080);
+ &data_word(0x0000001b, 0x00000036);
+&function_end_B("_x86_AES_encrypt");
+
+# void AES_encrypt (const void *inp,void *out,const AES_KEY *key);
+&public_label("AES_Te");
+&function_begin("AES_encrypt");
+ &mov ($acc,&wparam(0)); # load inp
+ &mov ($key,&wparam(2)); # load key
+
+ &call (&label("pic_point")); # make it PIC!
+ &set_label("pic_point");
+ &blindpop("ebp");
+ &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
+
+ &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");
+
+ &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");
+
+#------------------------------------------------------------------#
+
+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,&DWP(12,"esp")); }
+ else { &mov ($out,$s[0]); }
+ &and ($out,0xFF);
+ &mov ($out,&DWP(1024*0,$td,$out,4));
+
+ if ($i==3) { $tmp=$s[1]; }
+ &movz ($tmp,&HB($s[1]));
+ &xor ($out,&DWP(1024*1,$td,$tmp,4));
+
+ if ($i==3) { $tmp=$s[2]; &mov ($s[1],$acc); }
+ else { &mov ($tmp,$s[2]); }
+ &shr ($tmp,16);
+ &and ($tmp,0xFF);
+ &xor ($out,&DWP(1024*2,$td,$tmp,4));
+
+ if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(4,"esp")); }
+ else { &mov ($tmp,$s[3]); }
+ &shr ($tmp,24);
+ &xor ($out,&DWP(1024*3,$td,$tmp,4));
+ if ($i<2) { &mov (&DWP(4*$i,"esp"),$out); }
+ if ($i==3) { &mov ($s[3],&DWP(0,"esp")); }
+ &comment();
+}
+
+sub declast()
+{ my ($i,$td,@s)=@_;
+ my $tmp = $key;
+ my $out = $i==3?$s[0]:$acc;
+
+ if($i==3) { &mov ($key,&DWP(12,"esp")); }
+ else { &mov ($out,$s[0]); }
+ &and ($out,0xFF);
+ &mov ($out,&DWP(1024*4,$td,$out,4));
+ &and ($out,0x000000ff);
+
+ if ($i==3) { $tmp=$s[1]; }
+ &movz ($tmp,&HB($s[1]));
+ &mov ($tmp,&DWP(1024*4,$td,$tmp,4));
+ &and ($tmp,0x0000ff00);
+ &xor ($out,$tmp);
+
+ if ($i==3) { $tmp=$s[2]; &mov ($s[1],$acc); }
+ else { mov ($tmp,$s[2]); }
+ &shr ($tmp,16);
+ &and ($tmp,0xFF);
+ &mov ($tmp,&DWP(1024*4,$td,$tmp,4));
+ &and ($tmp,0x00ff0000);
+ &xor ($out,$tmp);
+
+ if ($i==3) { $tmp=$s[3]; &mov ($s[2],&DWP(4,"esp")); }
+ else { &mov ($tmp,$s[3]); }
+ &shr ($tmp,24);
+ &mov ($tmp,&DWP(1024*4,$td,$tmp,4));
+ &and ($tmp,0xff000000);
+ &xor ($out,$tmp);
+ if ($i<2) { &mov (&DWP(4*$i,"esp"),$out); }
+ if ($i==3) { &mov ($s[3],&DWP(0,"esp")); }
+}
+
+&public_label("AES_Td");
+&function_begin_B("_x86_AES_decrypt");
+ # allocate aligned stack frame
+ &mov ($acc,"esp");
+ &sub ("esp",20);
+ &and ("esp",-16);
+
+ &mov (&DWP(12,"esp"),$key); # save key
+ &mov (&DWP(16,"esp"),$acc); # save %esp
+
+ &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 (&DWP(8,"esp"),$acc); # end of key schedule
+ &align (4);
+ &set_label("loop");
+ &decstep(0,"ebp",$s0,$s3,$s2,$s1);
+ &decstep(1,"ebp",$s1,$s0,$s3,$s2);
+ &decstep(2,"ebp",$s2,$s1,$s0,$s3);
+ &decstep(3,"ebp",$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,&DWP(8,"esp"));
+ &mov (&DWP(12,"esp"),$key);
+ &jb (&label("loop"));
+ }
+ else {
+ &cmp ($acc,10);
+ &jle (&label("10rounds"));
+ &cmp ($acc,12);
+ &jle (&label("12rounds"));
+
+ &set_label("14rounds");
+ for ($i=1;$i<3;$i++) {
+ &decstep(0,"ebp",$s0,$s3,$s2,$s1);
+ &decstep(1,"ebp",$s1,$s0,$s3,$s2);
+ &decstep(2,"ebp",$s2,$s1,$s0,$s3);
+ &decstep(3,"ebp",$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 (&DWP(12,"esp"),$key); # advance rd_key
+ &set_label("12rounds");
+ for ($i=1;$i<3;$i++) {
+ &decstep(0,"ebp",$s0,$s3,$s2,$s1);
+ &decstep(1,"ebp",$s1,$s0,$s3,$s2);
+ &decstep(2,"ebp",$s2,$s1,$s0,$s3);
+ &decstep(3,"ebp",$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 (&DWP(12,"esp"),$key); # advance rd_key
+ &set_label("10rounds");
+ for ($i=1;$i<10;$i++) {
+ &decstep(0,"ebp",$s0,$s3,$s2,$s1);
+ &decstep(1,"ebp",$s1,$s0,$s3,$s2);
+ &decstep(2,"ebp",$s2,$s1,$s0,$s3);
+ &decstep(3,"ebp",$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,"ebp",$s0,$s3,$s2,$s1);
+ &declast(1,"ebp",$s1,$s0,$s3,$s2);
+ &declast(2,"ebp",$s2,$s1,$s0,$s3);
+ &declast(3,"ebp",$s3,$s2,$s1,$s0);
+
+ &mov ("esp",&DWP(16,"esp")); # restore %esp
+ &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);
+#Td1:
+ &data_word(0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96);
+ &data_word(0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93);
+ &data_word(0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525);
+ &data_word(0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f);
+ &data_word(0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1);
+ &data_word(0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6);
+ &data_word(0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da);
+ &data_word(0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44);
+ &data_word(0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd);
+ &data_word(0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4);
+ &data_word(0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245);
+ &data_word(0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994);
+ &data_word(0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7);
+ &data_word(0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a);
+ &data_word(0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5);
+ &data_word(0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c);
+ &data_word(0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1);
+ &data_word(0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a);
+ &data_word(0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475);
+ &data_word(0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51);
+ &data_word(0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46);
+ &data_word(0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff);
+ &data_word(0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777);
+ &data_word(0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db);
+ &data_word(0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000);
+ &data_word(0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e);
+ &data_word(0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627);
+ &data_word(0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a);
+ &data_word(0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e);
+ &data_word(0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16);
+ &data_word(0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d);
+ &data_word(0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8);
+ &data_word(0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd);
+ &data_word(0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34);
+ &data_word(0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863);
+ &data_word(0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420);
+ &data_word(0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d);
+ &data_word(0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0);
+ &data_word(0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722);
+ &data_word(0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef);
+ &data_word(0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836);
+ &data_word(0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4);
+ &data_word(0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462);
+ &data_word(0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5);
+ &data_word(0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3);
+ &data_word(0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b);
+ &data_word(0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8);
+ &data_word(0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6);
+ &data_word(0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6);
+ &data_word(0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0);
+ &data_word(0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315);
+ &data_word(0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f);
+ &data_word(0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df);
+ &data_word(0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f);
+ &data_word(0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e);
+ &data_word(0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13);
+ &data_word(0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89);
+ &data_word(0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c);
+ &data_word(0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf);
+ &data_word(0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886);
+ &data_word(0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f);
+ &data_word(0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41);
+ &data_word(0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490);
+ &data_word(0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042);
+#Td2:
+ &data_word(0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e);
+ &data_word(0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303);
+ &data_word(0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c);
+ &data_word(0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3);
+ &data_word(0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0);
+ &data_word(0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9);
+ &data_word(0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59);
+ &data_word(0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8);
+ &data_word(0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71);
+ &data_word(0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a);
+ &data_word(0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f);
+ &data_word(0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b);
+ &data_word(0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8);
+ &data_word(0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab);
+ &data_word(0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508);
+ &data_word(0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82);
+ &data_word(0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2);
+ &data_word(0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe);
+ &data_word(0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb);
+ &data_word(0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110);
+ &data_word(0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd);
+ &data_word(0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15);
+ &data_word(0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e);
+ &data_word(0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee);
+ &data_word(0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000);
+ &data_word(0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72);
+ &data_word(0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739);
+ &data_word(0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e);
+ &data_word(0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91);
+ &data_word(0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a);
+ &data_word(0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17);
+ &data_word(0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9);
+ &data_word(0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60);
+ &data_word(0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e);
+ &data_word(0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1);
+ &data_word(0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011);
+ &data_word(0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1);
+ &data_word(0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3);
+ &data_word(0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264);
+ &data_word(0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90);
+ &data_word(0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b);
+ &data_word(0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf);
+ &data_word(0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246);
+ &data_word(0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af);
+ &data_word(0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312);
+ &data_word(0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb);
+ &data_word(0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a);
+ &data_word(0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8);
+ &data_word(0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c);
+ &data_word(0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066);
+ &data_word(0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8);
+ &data_word(0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6);
+ &data_word(0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04);
+ &data_word(0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51);
+ &data_word(0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41);
+ &data_word(0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347);
+ &data_word(0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c);
+ &data_word(0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1);
+ &data_word(0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37);
+ &data_word(0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db);
+ &data_word(0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40);
+ &data_word(0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195);
+ &data_word(0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1);
+ &data_word(0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257);
+#Td3:
+ &data_word(0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27);
+ &data_word(0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3);
+ &data_word(0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02);
+ &data_word(0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362);
+ &data_word(0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe);
+ &data_word(0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3);
+ &data_word(0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952);
+ &data_word(0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9);
+ &data_word(0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9);
+ &data_word(0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace);
+ &data_word(0x63184adf, 0xe582311a, 0x97603351, 0x62457f53);
+ &data_word(0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08);
+ &data_word(0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b);
+ &data_word(0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55);
+ &data_word(0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837);
+ &data_word(0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216);
+ &data_word(0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269);
+ &data_word(0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6);
+ &data_word(0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6);
+ &data_word(0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e);
+ &data_word(0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6);
+ &data_word(0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550);
+ &data_word(0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9);
+ &data_word(0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8);
+ &data_word(0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000);
+ &data_word(0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a);
+ &data_word(0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d);
+ &data_word(0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36);
+ &data_word(0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b);
+ &data_word(0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12);
+ &data_word(0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b);
+ &data_word(0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e);
+ &data_word(0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f);
+ &data_word(0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb);
+ &data_word(0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4);
+ &data_word(0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6);
+ &data_word(0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129);
+ &data_word(0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1);
+ &data_word(0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9);
+ &data_word(0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033);
+ &data_word(0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4);
+ &data_word(0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad);
+ &data_word(0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e);
+ &data_word(0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3);
+ &data_word(0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225);
+ &data_word(0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b);
+ &data_word(0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f);
+ &data_word(0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815);
+ &data_word(0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0);
+ &data_word(0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2);
+ &data_word(0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7);
+ &data_word(0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691);
+ &data_word(0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496);
+ &data_word(0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165);
+ &data_word(0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b);
+ &data_word(0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6);
+ &data_word(0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13);
+ &data_word(0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147);
+ &data_word(0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7);
+ &data_word(0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44);
+ &data_word(0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3);
+ &data_word(0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d);
+ &data_word(0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156);
+ &data_word(0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8);
+#Td4:
+ &data_word(0x52525252, 0x09090909, 0x6a6a6a6a, 0xd5d5d5d5);
+ &data_word(0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838);
+ &data_word(0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e);
+ &data_word(0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb);
+ &data_word(0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282);
+ &data_word(0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787);
+ &data_word(0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444);
+ &data_word(0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb);
+ &data_word(0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232);
+ &data_word(0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d);
+ &data_word(0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0x0b0b0b0b);
+ &data_word(0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e);
+ &data_word(0x08080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666);
+ &data_word(0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2);
+ &data_word(0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949);
+ &data_word(0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525);
+ &data_word(0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464);
+ &data_word(0x86868686, 0x68686868, 0x98989898, 0x16161616);
+ &data_word(0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc);
+ &data_word(0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292);
+ &data_word(0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050);
+ &data_word(0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada);
+ &data_word(0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757);
+ &data_word(0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484);
+ &data_word(0x90909090, 0xd8d8d8d8, 0xabababab, 0x00000000);
+ &data_word(0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0x0a0a0a0a);
+ &data_word(0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x05050505);
+ &data_word(0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x06060606);
+ &data_word(0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f);
+ &data_word(0xcacacaca, 0x3f3f3f3f, 0x0f0f0f0f, 0x02020202);
+ &data_word(0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x03030303);
+ &data_word(0x01010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b);
+ &data_word(0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141);
+ &data_word(0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea);
+ &data_word(0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece);
+ &data_word(0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373);
+ &data_word(0x96969696, 0xacacacac, 0x74747474, 0x22222222);
+ &data_word(0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585);
+ &data_word(0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8);
+ &data_word(0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e);
+ &data_word(0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171);
+ &data_word(0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989);
+ &data_word(0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0x0e0e0e0e);
+ &data_word(0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b);
+ &data_word(0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b);
+ &data_word(0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020);
+ &data_word(0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe);
+ &data_word(0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4);
+ &data_word(0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333);
+ &data_word(0x88888888, 0x07070707, 0xc7c7c7c7, 0x31313131);
+ &data_word(0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959);
+ &data_word(0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f);
+ &data_word(0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9);
+ &data_word(0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0x0d0d0d0d);
+ &data_word(0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f);
+ &data_word(0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef);
+ &data_word(0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d);
+ &data_word(0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0);
+ &data_word(0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c);
+ &data_word(0x83838383, 0x53535353, 0x99999999, 0x61616161);
+ &data_word(0x17171717, 0x2b2b2b2b, 0x04040404, 0x7e7e7e7e);
+ &data_word(0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626);
+ &data_word(0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363);
+ &data_word(0x55555555, 0x21212121, 0x0c0c0c0c, 0x7d7d7d7d);
+&function_end_B("_x86_AES_decrypt");
+
+# void AES_decrypt (const void *inp,void *out,const AES_KEY *key);
+&public_label("AES_Td");
+&function_begin("AES_decrypt");
+ &mov ($acc,&wparam(0)); # load inp
+ &mov ($key,&wparam(2)); # load key
+
+ &call (&label("pic_point")); # make it PIC!
+ &set_label("pic_point");
+ &blindpop("ebp");
+ &lea ("ebp",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp"));
+
+ &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");
+
+ &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);
+&public_label("AES_Te");
+&public_label("AES_Td");
+&function_begin("AES_cbc_encrypt");
+ &mov ($s2 eq "ecx"? $s2 : "",&wparam(2)); # load len
+ &cmp ($s2,0);
+ &je (&label("enc_out"));
+
+ &call (&label("pic_point")); # make it PIC!
+ &set_label("pic_point");
+ &blindpop("ebp");
+
+ &cmp (&wparam(5),0);
+ &je (&label("DECRYPT"));
+
+ &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
+
+ &mov ($acc,&wparam(0)); # load inp
+ &mov ($key,&wparam(4)); # load ivp
+
+ &test ($s2,~15);
+ &jz (&label("enc_tail")); # short input...
+
+ &mov ($s0,&DWP(0,$key)); # load iv
+ &mov ($s1,&DWP(4,$key));
+
+ &align (4);
+ &set_label("enc_loop");
+ &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,&wparam(3)); # load key
+ &call ("_x86_AES_encrypt");
+
+ &mov ($acc,&wparam(0)); # load inp
+ &mov ($key,&wparam(1)); # 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,&wparam(2)); # load len
+
+ &lea ($acc,&DWP(16,$acc));
+ &mov (&wparam(0),$acc); # save inp
+
+ &lea ($s3,&DWP(16,$key));
+ &mov (&wparam(1),$s3); # save out
+
+ &sub ($s2,16);
+ &test ($s2,~15);
+ &mov (&wparam(2),$s2); # save len
+ &jnz (&label("enc_loop"));
+ &test ($s2,15);
+ &jnz (&label("enc_tail"));
+ &mov ($acc,&wparam(4)); # load ivp
+ &mov ($s2,&DWP(8,$key)); # restore last dwords
+ &mov ($s3,&DWP(12,$key));
+ &mov (&DWP(0,$acc),$s0); # save iv
+ &mov (&DWP(4,$acc),$s1);
+ &mov (&DWP(8,$acc),$s2);
+ &mov (&DWP(12,$acc),$s3);
+ &set_label("enc_out");
+ &function_end_A();
+
+ &align (4);
+ &set_label("enc_tail");
+ &push ($key eq "edi" ? $key : ""); # push ivp
+ &pushf ();
+ &mov ($key,&wparam(1)); # load out
+ &mov ($s1,16);
+ &sub ($s1,$s2);
+ &cmp ($key,$acc); # compare with inp
+ &je (&label("enc_in_place"));
+ &data_word(0x90A4F3FC); # cld; rep movsb; nop # 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);
+ &data_word(0x90AAF3FC); # cld; rep stosb; nop # zero tail
+ &popf ();
+ &pop ($key); # pop ivp
+
+ &mov ($acc,&wparam(1)); # output as input
+ &mov ($s0,&DWP(0,$key));
+ &mov ($s1,&DWP(4,$key));
+ &mov (&wparam(2),16); # len=16
+ &jmp (&label("enc_loop")); # one more spin...
+
+#----------------------------- DECRYPT -----------------------------#
+&align (4);
+&set_label("DECRYPT");
+ &stack_push(5); # allocate temp + ivp
+
+ &lea ("ebp",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp"));
+
+ &mov ($acc,&wparam(0)); # load inp
+ &cmp ($acc,&wparam(1));
+ &je (&label("dec_in_place")); # in-place processing...
+
+ &mov ($key,&wparam(4)); # load ivp
+ &mov (&swtmp(4),$key);
+
+ &align (4);
+ &set_label("dec_loop");
+ &mov ($s0,&DWP(0,$acc)); # read input
+ &mov ($s1,&DWP(4,$acc));
+ &mov ($s2,&DWP(8,$acc));
+ &mov ($s3,&DWP(12,$acc));
+
+ &mov ($key,&wparam(3)); # load key
+ &call ("_x86_AES_decrypt");
+
+ &mov ($key,&swtmp(4)); # load ivp
+ &mov ($acc,&wparam(2)); # 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("dec_partial"));
+ &mov (&wparam(2),$acc); # save len
+ &mov ($acc,&wparam(0)); # load inp
+ &mov ($key,&wparam(1)); # 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 (&swtmp(4),$acc); # save ivp
+ &lea ($acc,&DWP(16,$acc));
+ &mov (&wparam(0),$acc); # save inp
+
+ &lea ($key,&DWP(16,$key));
+ &mov (&wparam(1),$key); # save out
+
+ &jnz (&label("dec_loop"));
+ &mov ($key,&swtmp(4)); # load temp ivp
+ &set_label("dec_end");
+ &mov ($acc,&wparam(4)); # 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("dec_out"));
+
+ &align (4);
+ &set_label("dec_partial");
+ &lea ($key,&swtmp(0));
+ &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,$acc));
+ &mov ($acc eq "esi" ? $acc : "",$key);
+ &mov ($key eq "edi" ? $key : "",&wparam(1));
+ &pushf ();
+ &data_word(0x90A4F3FC); # cld; rep movsb; nop # copy output
+ &popf ();
+ &mov ($key,&wparam(0)); # load temp ivp
+ &jmp (&label("dec_end"));
+
+ &align (4);
+ &set_label("dec_in_place");
+ &set_label("dec_in_place_loop");
+ &lea ($key,&swtmp(0));
+ &mov ($s0,&DWP(0,$acc)); # read input
+ &mov ($s1,&DWP(4,$acc));
+ &mov ($s2,&DWP(8,$acc));
+ &mov ($s3,&DWP(12,$acc));
+
+ &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,&wparam(3)); # load key
+ &call ("_x86_AES_decrypt");
+
+ &mov ($key,&wparam(4)); # load ivp
+ &mov ($acc,&wparam(1)); # 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));
+ &mov (&wparam(1),$acc); # save out
+
+ &lea ($acc,&swtmp(0));
+ &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,&wparam(0)); # load inp
+
+ &lea ($acc,&DWP(16,$acc));
+ &mov (&wparam(0),$acc); # save inp
+
+ &mov ($s2,&wparam(2)); # load len
+ &sub ($s2,16);
+ &jc (&label("dec_in_place_partial"));
+ &mov (&wparam(2),$s2); # save len
+ &jnz (&label("dec_in_place_loop"));
+ &jmp (&label("dec_out"));
+
+ &align (4);
+ &set_label("dec_in_place_partial");
+ # one can argue if this is actually required...
+ &mov ($key eq "edi" ? $key : "",&wparam(1));
+ &lea ($acc eq "esi" ? $acc : "",&swtmp(0));
+ &lea ($key,&DWP(0,$key,$s2));
+ &lea ($acc,&DWP(16,$acc,$s2));
+ &neg ($s2 eq "ecx" ? $s2 : "");
+ &pushf ();
+ &data_word(0x90A4F3FC); # cld; rep movsb; nop # restore tail
+ &popf ();
+
+ &align (4);
+ &set_label("dec_out");
+ &stack_pop(5);
+&function_end("AES_cbc_encrypt");
+
+#------------------------------------------------------------------#
+
+sub enckey()
+{
+ &movz ("esi",&LB("edx")); # rk[i]>>0
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &movz ("esi",&HB("edx")); # rk[i]>>8
+ &and ("ebx",0xFF000000);
+ &xor ("eax","ebx");
+
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &shr ("edx",16);
+ &and ("ebx",0x000000FF);
+ &movz ("esi",&LB("edx")); # rk[i]>>16
+ &xor ("eax","ebx");
+
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &movz ("esi",&HB("edx")); # rk[i]>>24
+ &and ("ebx",0x0000FF00);
+ &xor ("eax","ebx");
+
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &and ("ebx",0x00FF0000);
+ &xor ("eax","ebx");
+
+ &xor ("eax",&DWP(1024,"ebp","ecx",4)); # rcon
+}
+
+# int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+# AES_KEY *key)
+&public_label("AES_Te");
+&function_begin("AES_set_encrypt_key");
+ &mov ("esi",&wparam(0)); # user supplied key
+ &mov ("edi",&wparam(2)); # private key schedule
+
+ &test ("esi",-1);
+ &jz (&label("badpointer"));
+ &test ("edi",-1);
+ &jz (&label("badpointer"));
+
+ &call (&label("pic_point"));
+ &set_label("pic_point");
+ &blindpop("ebp");
+ &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
+ &add ("ebp",1024*4); # skip to Te4
+
+ &mov ("ecx",&wparam(1)); # 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
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &movz ("esi",&HB("edx")); # rk[11]>>8
+ &and ("ebx",0x000000FF);
+ &xor ("eax","ebx");
+
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &shr ("edx",16);
+ &and ("ebx",0x0000FF00);
+ &movz ("esi",&LB("edx")); # rk[11]>>16
+ &xor ("eax","ebx");
+
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &movz ("esi",&HB("edx")); # rk[11]>>24
+ &and ("ebx",0x00FF0000);
+ &xor ("eax","ebx");
+
+ &mov ("ebx",&DWP(0,"ebp","esi",4));
+ &and ("ebx",0xFF000000);
+ &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("AES_set_encrypt_key");
+
+sub deckey()
+{ my ($i,$ptr,$te4,$td) = @_;
+
+ &mov ("eax",&DWP($i,$ptr));
+ &mov ("edx","eax");
+ &movz ("ebx",&HB("eax"));
+ &shr ("edx",16);
+ &and ("eax",0xFF);
+ &movz ("eax",&BP(0,$te4,"eax",4));
+ &movz ("ebx",&BP(0,$te4,"ebx",4));
+ &mov ("eax",&DWP(1024*0,$td,"eax",4));
+ &xor ("eax",&DWP(1024*1,$td,"ebx",4));
+ &movz ("ebx",&HB("edx"));
+ &and ("edx",0xFF);
+ &movz ("edx",&BP(0,$te4,"edx",4));
+ &movz ("ebx",&BP(0,$te4,"ebx",4));
+ &xor ("eax",&DWP(1024*2,$td,"edx",4));
+ &xor ("eax",&DWP(1024*3,$td,"ebx",4));
+ &mov (&DWP($i,$ptr),"eax");
+}
+
+# int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+# AES_KEY *key)
+&public_label("AES_Td");
+&public_label("AES_Te");
+&function_begin_B("AES_set_decrypt_key");
+ &mov ("eax",&wparam(0));
+ &mov ("ecx",&wparam(1));
+ &mov ("edx",&wparam(2));
+ &sub ("esp",12);
+ &mov (&DWP(0,"esp"),"eax");
+ &mov (&DWP(4,"esp"),"ecx");
+ &mov (&DWP(8,"esp"),"edx");
+ &call ("AES_set_encrypt_key");
+ &add ("esp",12);
+ &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
+
+ &align (4);
+ &set_label("invert"); # 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"));
+
+ &call (&label("pic_point"));
+ &set_label("pic_point");
+ blindpop("ebp");
+ &lea ("edi",&DWP(&label("AES_Td")."-".&label("pic_point"),"ebp"));
+ &lea ("ebp",&DWP(&label("AES_Te")."-".&label("pic_point"),"ebp"));
+ &add ("ebp",1024*4); # skip to Te4
+
+ &mov ("esi",&wparam(2));
+ &mov ("ecx",&DWP(240,"esi")); # pull number of rounds
+ &dec ("ecx");
+ &align (4);
+ &set_label("permute"); # permute the key schedule
+ &add ("esi",16);
+ &deckey (0,"esi","ebp","edi");
+ &deckey (4,"esi","ebp","edi");
+ &deckey (8,"esi","ebp","edi");
+ &deckey (12,"esi","ebp","edi");
+ &dec ("ecx");
+ &jnz (&label("permute"));
+
+ &xor ("eax","eax"); # return success
+&function_end("AES_set_decrypt_key");
+
+&asm_finish();
diff --git a/crypto/amd64cpuid.pl b/crypto/amd64cpuid.pl
new file mode 100644
index 0000000000..097f6b8d5c
--- /dev/null
+++ b/crypto/amd64cpuid.pl
@@ -0,0 +1,139 @@
+#!/usr/bin/env perl
+
+$output=shift;
+$win64a=1 if ($output =~ /win64a\.[s|asm]/);
+open STDOUT,">$output" || die "can't open $output: $!";
+
+print<<___ if(defined($win64a));
+_TEXT SEGMENT
+PUBLIC OPENSSL_rdtsc
+ALIGN 16
+OPENSSL_rdtsc PROC
+ rdtsc
+ shl rdx,32
+ or rax,rdx
+ ret
+OPENSSL_rdtsc ENDP
+
+PUBLIC OPENSSL_atomic_add
+ALIGN 16
+OPENSSL_atomic_add PROC
+ mov eax,DWORD PTR[rcx]
+\$Lspin: lea r8,DWORD PTR[rdx+rax]
+lock cmpxchg DWORD PTR[rcx],r8d
+ jne \$Lspin
+ mov eax,r8d
+ cdqe
+ ret
+OPENSSL_atomic_add ENDP
+
+PUBLIC OPENSSL_wipe_cpu
+ALIGN 16
+OPENSSL_wipe_cpu PROC
+ 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[rsp+8]
+ ret
+OPENSSL_wipe_cpu ENDP
+
+OPENSSL_ia32_cpuid PROC
+ mov r8,rbx
+ mov eax,1
+ cpuid
+ shl rcx,32
+ mov eax,edx
+ mov rbx,r8
+ or rax,rcx
+ ret
+OPENSSL_ia32_cpuid ENDP
+_TEXT ENDS
+
+CRT\$XIU SEGMENT
+EXTRN OPENSSL_cpuid_setup:PROC
+DQ OPENSSL_cpuid_setup
+CRT\$XIU ENDS
+END
+___
+print<<___ if(!defined($win64a));
+.text
+.globl OPENSSL_rdtsc
+.align 16
+OPENSSL_rdtsc:
+ rdtsc
+ shl \$32,%rdx
+ or %rdx,%rax
+ ret
+.size OPENSSL_rdtsc,.-OPENSSL_rdtsc
+
+.globl OPENSSL_atomic_add
+.type OPENSSL_atomic_add,\@function
+.align 16
+OPENSSL_atomic_add:
+ movl (%rdi),%eax
+.Lspin: lea (%rsi,%rax),%r8
+lock; cmpxchg %r8d,(%rdi)
+ jne .Lspin
+ mov %r8d,%eax
+ cdqe
+ ret
+.size OPENSSL_atomic_add,.-OPENSSL_atomic_add
+
+.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
+ xor %rcx,%rcx
+ xor %rdx,%rdx
+ xor %rsi,%rsi
+ xor %rdi,%rdi
+ xor %r8,%r8
+ xor %r9,%r9
+ xor %r10,%r10
+ xor %r11,%r11
+ lea 8(%rsp),%rax
+ ret
+.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+
+.globl OPENSSL_ia32_cpuid
+.align 16
+OPENSSL_ia32_cpuid:
+ mov %rbx,%r8
+ mov \$1,%eax
+ cpuid
+ shl \$32,%rcx
+ mov %edx,%eax
+ mov %r8,%rbx
+ or %rcx,%rax
+ ret
+.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
+
+.section .init
+ call OPENSSL_cpuid_setup
+ .align 16
+___
diff --git a/crypto/engine/eng_padlock.c b/crypto/engine/eng_padlock.c
new file mode 100644
index 0000000000..4f64a06fb0
--- /dev/null
+++ b/crypto/engine/eng_padlock.c
@@ -0,0 +1,1091 @@
+/*
+ * 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/crypto.h>
+#include <openssl/dso.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+#include <openssl/rand.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(__i386__) || defined(__i386) || defined(_M_IX86)
+# define COMPILE_HW_PADLOCK
+static ENGINE *ENGINE_padlock (void);
+# endif
+#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
+}
+
+#ifdef COMPILE_HW_PADLOCK
+/* We do these includes here to avoid header problems on platforms that
+ do not have the VIA padlock anyway... */
+#ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+#else
+# include <stdlib.h>
+#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 */
+static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+
+/* 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 */
+static int padlock_aes_align_required = 1;
+
+/* ===== 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) ||
+
+ (padlock_use_ace && !ENGINE_set_ciphers (e, padlock_ciphers)) ||
+ (padlock_use_rng && !ENGINE_set_RAND (e, &padlock_rand))) {
+ return 0;
+ }
+
+ /* Everything looks good */
+ return 1;
+}
+
+/* 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;
+}
+
+/* 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 ===== */
+
+/* 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 algo:3;
+ int keygen:1;
+ int interm:1;
+ 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;
+
+/*
+ * =======================================================
+ * 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;
+}
+
+/* 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++;
+ }
+}
+
+/* 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");
+}
+
+/*
+ * 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"
+" bt $30,(%%esp)\n"
+" jnc 1f\n"
+" cmp %2,%1\n"
+" je 1f\n"
+" mov %2,%0\n"
+" popfl\n"
+" sub $4,%%esp\n"
+"1: add $4,%%esp"
+ :"+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"); \
+ 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 */
+
+/* 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
+ mov padlock_saved_context,ecx
+ popfd
+ sub esp,4
+ skip: add esp,4
+ }
+}
+
+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 ===== */
+
+#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,
+#if 0
+ NID_aes_192_cfb, /* FIXME: AES192/256 CFB/OFB don't work. */
+ NID_aes_192_ofb,
+#endif
+
+ NID_aes_256_ecb,
+ NID_aes_256_cbc,
+#if 0
+ NID_aes_256_cfb,
+ NID_aes_256_ofb,
+#endif
+};
+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))
+
+/* 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, \
+ AES_BLOCK_SIZE, \
+ 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. */
+ 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 (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 4096 /* 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;
+
+ if (nbytes == 0)
+ return 1;
+ if (nbytes % AES_BLOCK_SIZE)
+ return 0; /* are we expected to do tail processing? */
+
+ /* 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... */
+ if (!padlock_aes_align_required)
+ 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)
+ 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 (cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ goto cfb_shortcut;
+ 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;
+
+ } while (nbytes -= chunk);
+ memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
+ break;
+
+ case EVP_CIPH_OFB_MODE:
+ memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE);
+ 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);
+ 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;
+}
+
+/* ===== 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 */
+};
+
+#endif /* COMPILE_HW_PADLOCK */
+
+#endif /* !OPENSSL_NO_HW_PADLOCK */
+#endif /* !OPENSSL_NO_HW */
diff --git a/crypto/ia64cpuid.S b/crypto/ia64cpuid.S
new file mode 100644
index 0000000000..a800527a58
--- /dev/null
+++ b/crypto/ia64cpuid.S
@@ -0,0 +1,9 @@
+// Works on all IA-64 platforms: Linux, HP-UX, Win64i...
+// On Win64i compile with ias.exe.
+.text
+.global OPENSSL_rdtsc#
+.proc OPENSSL_rdtsc#
+OPENSSL_rdtsc:
+ mov r8=ar.itc
+ br.ret b0
+.endp OPENSSL_rdtsc#
diff --git a/crypto/rc4/asm/rc4-ia64.S b/crypto/rc4/asm/rc4-ia64.S
new file mode 100644
index 0000000000..b517d2e88f
--- /dev/null
+++ b/crypto/rc4/asm/rc4-ia64.S
@@ -0,0 +1,157 @@
+// ====================================================================
+// 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.
+// ====================================================================
+
+.ident "rc4-ia64.S, Version 1.1"
+.ident "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+// What's wrong with compiler generated code? Because of the nature of
+// C language, compiler doesn't [dare to] reorder load and stores. But
+// being memory-bound, RC4 should benefit from reorder [on in-order-
+// execution core such as IA-64]. But what can we reorder? At the very
+// least we can safely reorder references to key schedule in respect
+// to input and output streams. Secondly, from the first [close] glance
+// it appeared that it's possible to pull up some references to
+// elements of the key schedule itself. Original rationale ["prior
+// loads are not safe only for "degenerated" key schedule, when some
+// elements equal to the same value"] was kind of sloppy. I should have
+// formulated as it really was: if we assume that pulling up reference
+// to key[x+1] is not safe, then it would mean that key schedule would
+// "degenerate," which is never the case. The problem is that this
+// holds true in respect to references to key[x], but not to key[y].
+// Legitimate "collisions" do occur within every 256^2 bytes window.
+// Fortunately there're enough free instruction slots to keep prior
+// reference to key[x+1], detect "collision" and compensate for it.
+// All this without sacrificing a single clock cycle:-)
+// Furthermore. In order to compress loop body to the minimum, I chose
+// to deploy deposit instruction, which substitutes for the whole
+// key->data+((x&255)<<log2(sizeof(key->data[0]))). This unfortunately
+// requires key->data to be aligned at sizeof(key->data) boundary.
+// This is why you'll find "RC4_INT pad[512-256-2];" addenum to RC4_KEY
+// and "d=(RC4_INT *)(((size_t)(d+255))&~(sizeof(key->data)-1));" in
+// rc4_skey.c [and rc4_enc.c, where it's retained for debugging
+// purposes]. Throughput is ~210MBps on 900MHz CPU, which is is >3x
+// faster than gcc generated code and +30% - if compared to HP-UX C.
+// Unrolling loop below should give >30% on top of that...
+
+.text
+.explicit
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+# define ADDP addp4
+#else
+# define ADDP add
+#endif
+
+#define SZ 4 // this is set to sizeof(RC4_INT)
+// SZ==4 seems to be optimal. At least SZ==8 is not any faster, not for
+// assembler implementation, while SZ==1 code is ~30% slower.
+#if SZ==1 // RC4_INT is unsigned char
+# define LDKEY ld1
+# define STKEY st1
+# define OFF 0
+#elif SZ==4 // RC4_INT is unsigned int
+# define LDKEY ld4
+# define STKEY st4
+# define OFF 2
+#elif SZ==8 // RC4_INT is unsigned long
+# define LDKEY ld8
+# define STKEY st8
+# define OFF 3
+#endif
+
+out=r8; // [expanded] output pointer
+inp=r9; // [expanded] output pointer
+prsave=r10;
+key=r28; // [expanded] pointer to RC4_KEY
+ksch=r29; // (key->data+255)[&~(sizeof(key->data)-1)]
+xx=r30;
+yy=r31;
+
+// void RC4(RC4_KEY *key,size_t len,const void *inp,void *out);
+.global RC4#
+.proc RC4#
+.align 32
+.skip 16
+RC4:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+ .save ar.lc,r3
+ .save pr,prsave
+{ .mii; alloc r2=ar.pfs,4,12,0,16
+ mov prsave=pr
+ ADDP key=0,in0 };;
+{ .mib; cmp.eq p6,p0=0,in1 // len==0?
+ mov r3=ar.lc
+(p6) br.ret.spnt.many b0 };; // emergency exit
+
+ .body
+ .rotr dat[4],key_x[4],tx[2],rnd[2],key_y[2],ty[1];
+
+{ .mib; LDKEY xx=[key],SZ // load key->x
+ add in1=-1,in1 // adjust len for loop counter
+ nop.b 0 }
+{ .mib; ADDP inp=0,in2
+ ADDP out=0,in3
+ brp.loop.imp .Ltop,.Lexit-16 };;
+{ .mmi; LDKEY yy=[key] // load key->y
+ add ksch=(255+1)*SZ,key // as ksch will be used with
+ // deposit instruction only,
+ // I don't have to &~255...
+ mov ar.lc=in1 }
+{ .mmi; mov key_y[1]=r0 // guarantee inequality
+ // in first iteration
+ add xx=1,xx
+ mov pr.rot=1<<16 };;
+{ .mii; nop.m 0
+ dep key_x[1]=xx,ksch,OFF,8
+ mov ar.ec=3 };; // note that epilogue counter
+ // is off by 1. I compensate
+ // for this at exit...
+.Ltop:
+// The loop is scheduled for 3*(n+2) spin-rate on Itanium 2, which
+// theoretically gives asymptotic performance of clock frequency
+// divided by 3 bytes per seconds, or 500MBps on 1.5GHz CPU. Measured
+// performance however is distinctly lower than 1/4:-( The culplrit
+// seems to be *(out++)=dat, which inadvertently splits the bundle,
+// even though there is M-port available... Unrolling is due...
+// Unrolled loop should collect output with variable shift instruction
+// in order to avoid starvation for integer shifter... It should be
+// possible to get pretty close to theoretical peak...
+{ .mmi; (p16) LDKEY tx[0]=[key_x[1]] // tx=key[xx]
+ (p17) LDKEY ty[0]=[key_y[1]] // ty=key[yy]
+ (p18) dep rnd[1]=rnd[1],ksch,OFF,8} // &key[(tx+ty)&255]
+{ .mmi; (p19) st1 [out]=dat[3],1 // *(out++)=dat
+ (p16) add xx=1,xx // x++
+ (p16) cmp.ne.unc p20,p21=key_x[1],key_y[1] };;
+{ .mmi; (p18) LDKEY rnd[1]=[rnd[1]] // rnd=key[(tx+ty)&255]
+ (p16) ld1 dat[0]=[inp],1 // dat=*(inp++)
+ (p16) dep key_x[0]=xx,ksch,OFF,8 } // &key[xx&255]
+.pred.rel "mutex",p20,p21
+{ .mmi; (p21) add yy=yy,tx[1] // (p16)
+ (p20) add yy=yy,tx[0] // (p16) y+=tx
+ (p21) mov tx[0]=tx[1] };; // (p16)
+{ .mmi; (p17) STKEY [key_y[1]]=tx[1] // key[yy]=tx
+ (p17) STKEY [key_x[2]]=ty[0] // key[xx]=ty
+ (p16) dep key_y[0]=yy,ksch,OFF,8 } // &key[yy&255]
+{ .mmb; (p17) add rnd[0]=tx[1],ty[0] // tx+=ty
+ (p18) xor dat[2]=dat[2],rnd[1] // dat^=rnd
+ br.ctop.sptk .Ltop };;
+.Lexit:
+{ .mib; STKEY [key]=yy,-SZ // save key->y
+ mov pr=prsave,0x1ffff
+ nop.b 0 }
+{ .mib; st1 [out]=dat[3],1 // compensate for truncated
+ // epilogue counter
+ add xx=-1,xx
+ nop.b 0 };;
+{ .mib; STKEY [key]=xx // save key->x
+ mov ar.lc=r3
+ br.ret.sptk.many b0 };;
+.endp RC4#
diff --git a/crypto/sha/asm/sha1-ia64.pl b/crypto/sha/asm/sha1-ia64.pl
new file mode 100644
index 0000000000..cb9dfad124
--- /dev/null
+++ b/crypto/sha/asm/sha1-ia64.pl
@@ -0,0 +1,549 @@
+#!/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.
+# ====================================================================
+#
+# 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. As of this moment
+# performance under little-endian OS such as Linux and Windows will be
+# a bit lower, because data has to be picked in reverse byte-order.
+# It's possible to resolve this issue by implementing third function,
+# sha1_block_asm_data_order_aligned, which would temporarily flip
+# BE field in User Mask register...
+
+$code=<<___;
+.ident \"sha1-ia64.s, version 1.0\"
+.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"; }
+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); }
+
+#$human=1;
+if ($human) { # useful for visual code auditing...
+ ($A,$B,$C,$D,$E,$T) = ("A","B","C","D","E","T");
+ ($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,$T) = ("loc0","loc1","loc2","loc3","loc4","loc5");
+ ($h0,$h1,$h2,$h3,$h4) = ("loc6","loc7","loc8","loc9","loc10");
+ ($K_00_19, $K_20_39, $K_40_59, $K_60_79) =
+ ( "r14", "r15", "loc11", "loc12" );
+ @X= ( "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" );
+}
+
+sub BODY_00_15 {
+local *code=shift;
+local ($i,$a,$b,$c,$d,$e,$f,$unaligned)=@_;
+
+if ($unaligned) {
+ $code.=<<___;
+{ .mmi; ld1 tmp0=[inp],2 // MSB
+ ld1 tmp1=[tmp3],2 };;
+{ .mmi; ld1 tmp2=[inp],2
+ ld1 $X[$i&0xf]=[tmp3],2 // LSB
+ dep tmp1=tmp0,tmp1,8,8 };;
+{ .mii; cmp.ne p16,p0=r0,r0 // no misaligned prefetch
+ dep $X[$i&0xf]=tmp2,$X[$i&0xf],8,8;;
+ dep $X[$i&0xf]=tmp1,$X[$i&0xf],16,16 };;
+{ .mmi; nop.m 0
+___
+ }
+elsif ($i<15) {
+ $code.=<<___;
+{ .mmi; ld4 $X[($i+1)&0xf]=[inp],4 // prefetch
+___
+ }
+else {
+ $code.=<<___;
+{ .mmi; nop.m 0
+___
+ }
+if ($i<15) {
+ $code.=<<___;
+ and tmp0=$c,$b
+ dep.z tmp5=$a,5,27 } // a<<5
+{ .mmi; andcm tmp1=$d,$b
+ add tmp4=$e,$K_00_19 };;
+{ .mmi; or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
+ add $f=tmp4,$X[$i&0xf] // f=xi+e+K_00_19
+ extr.u tmp1=$a,27,5 };; // a>>27
+{ .mib; add $f=$f,tmp0 // f+=F_00_19(b,c,d)
+ shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30)
+{ .mib; or tmp1=tmp1,tmp5 // ROTATE(a,5)
+ mux2 tmp6=$a,0x44 };; // see b in next iteration
+{ .mii; add $f=$f,tmp1 // f+=ROTATE(a,5)
+ mux2 $X[$i&0xf]=$X[$i&0xf],0x44
+ nop.i 0 };;
+
+___
+ }
+else {
+ $code.=<<___;
+ and tmp0=$c,$b
+ dep.z tmp5=$a,5,27 } // a<<5 ;;?
+{ .mmi; andcm tmp1=$d,$b
+ add tmp4=$e,$K_00_19 };;
+{ .mmi; or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
+ add $f=tmp4,$X[$i&0xf] // f=xi+e+K_00_19
+ extr.u tmp1=$a,27,5 } // a>>27
+{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
+ xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
+ nop.i 0 };;
+{ .mmi; add $f=$f,tmp0 // f+=F_00_19(b,c,d)
+ xor tmp2=tmp2,tmp3 // +1
+ 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 $f=$f,tmp1 // f+=ROTATE(a,5)
+ shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+ mux2 $X[$i&0xf]=$X[$i&0xf],0x44 };;
+
+___
+ }
+}
+
+sub BODY_16_19 {
+local *code=shift;
+local ($i,$a,$b,$c,$d,$e,$f)=@_;
+
+$code.=<<___;
+{ .mmi; mov $X[$i&0xf]=$f // Xupdate
+ and tmp0=$c,$b
+ dep.z tmp5=$a,5,27 } // a<<5
+{ .mmi; andcm tmp1=$d,$b
+ add tmp4=$e,$K_00_19 };;
+{ .mmi; or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d)
+ add $f=$f,tmp4 // f+=e+K_00_19
+ extr.u tmp1=$a,27,5 } // a>>27
+{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
+ xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
+ nop.i 0 };;
+{ .mmi; add $f=$f,tmp0 // f+=F_00_19(b,c,d)
+ xor tmp2=tmp2,tmp3 // +1
+ 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 $f=$f,tmp1 // f+=ROTATE(a,5)
+ shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+ nop.i 0 };;
+
+___
+}
+
+sub BODY_20_39 {
+local *code=shift;
+local ($i,$a,$b,$c,$d,$e,$f,$Konst)=@_;
+ $Konst = $K_20_39 if (!defined($Konst));
+
+if ($i<79) {
+$code.=<<___;
+{ .mib; mov $X[$i&0xf]=$f // Xupdate
+ dep.z tmp5=$a,5,27 } // a<<5
+{ .mib; xor tmp0=$c,$b
+ add tmp4=$e,$Konst };;
+{ .mmi; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d
+ add $f=$f,tmp4 // f+=e+K_20_39
+ extr.u tmp1=$a,27,5 } // a>>27
+{ .mmi; xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
+ xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
+ nop.i 0 };;
+{ .mmi; add $f=$f,tmp0 // f+=F_20_39(b,c,d)
+ xor tmp2=tmp2,tmp3 // +1
+ 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 $f=$f,tmp1 // f+=ROTATE(a,5)
+ shrp $e=tmp2,tmp2,31 // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+ nop.i 0 };;
+
+___
+}
+else {
+$code.=<<___;
+{ .mib; mov $X[$i&0xf]=$f // Xupdate
+ dep.z tmp5=$a,5,27 } // a<<5
+{ .mib; xor tmp0=$c,$b
+ add tmp4=$e,$Konst };;
+{ .mib; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d
+ extr.u tmp1=$a,27,5 } // a>>27
+{ .mib; add $f=$f,tmp4 // f+=e+K_20_39
+ add $h1=$h1,$a };; // wrap up
+{ .mmi;
+(p16) ld4.s $X[0]=[inp],4 // non-faulting prefetch
+ add $f=$f,tmp0 // f+=F_20_39(b,c,d)
+ shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) ;;?
+{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5)
+ add $h3=$h3,$c };; // wrap up
+{ .mib; add tmp3=1,inp // used in unaligned codepath
+ add $f=$f,tmp1 } // f+=ROTATE(a,5)
+{ .mib; add $h2=$h2,$b // wrap up
+ add $h4=$h4,$d };; // wrap up
+
+___
+}
+}
+
+sub BODY_40_59 {
+local *code=shift;
+local ($i,$a,$b,$c,$d,$e,$f)=@_;
+
+$code.=<<___;
+{ .mmi; mov $X[$i&0xf]=$f // Xupdate
+ and tmp0=$c,$b
+ dep.z tmp5=$a,5,27 } // a<<5
+{ .mmi; and tmp1=$d,$b
+ add tmp4=$e,$K_40_59 };;
+{ .mmi; or tmp0=tmp0,tmp1 // (b&c)|(b&d)
+ add $f=$f,tmp4 // f+=e+K_40_59
+ extr.u tmp1=$a,27,5 } // a>>27
+{ .mmi; and tmp4=$c,$d
+ xor tmp2=$X[($i+0+1)&0xf],$X[($i+2+1)&0xf] // +1
+ xor tmp3=$X[($i+8+1)&0xf],$X[($i+13+1)&0xf] // +1
+ };;
+{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5)
+ xor tmp2=tmp2,tmp3 // +1
+ shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30)
+{ .mmi; or tmp0=tmp0,tmp4 // F_40_59(b,c,d)=(b&c)|(b&d)|(c&d)
+ mux2 tmp6=$a,0x44 };; // see b in next iteration
+{ .mii; add $f=$f,tmp0 // f+=F_40_59(b,c,d)
+ shrp $e=tmp2,tmp2,31;; // f+1=ROTATE(x[0]^x[2]^x[8]^x[13],1)
+ add $f=$f,tmp1 };; // f+=ROTATE(a,5)
+
+___
+}
+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_asm_host_order(SHA_CTX *c,const void *p,size_t num);
+.global sha1_block_asm_host_order#
+.proc sha1_block_asm_host_order#
+.align 32
+sha1_block_asm_host_order:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r0
+ .save ar.lc,r3
+{ .mmi; alloc tmp1=ar.pfs,3,15,0,0
+ $ADDP tmp0=4,ctx
+ mov r3=ar.lc }
+{ .mmi; $ADDP ctx=0,ctx
+ $ADDP inp=0,inp
+ mov r2=pr };;
+tmp4=in2;
+tmp5=loc13;
+tmp6=loc14;
+ .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; ld4 $X[0]=[inp],4 // prefetch
+ cmp.ne p16,p0=r0,in2 // prefecth at loop end
+ mov ar.lc=in2 };; // brp.loop.imp: too far
+
+.Lhtop:
+{ .mmi; mov $A=$h0
+ mov $B=$h1
+ mux2 tmp6=$h1,0x44 }
+{ .mmi; mov $C=$h2
+ mov $D=$h3
+ mov $E=$h4 };;
+
+___
+
+ &BODY_00_15(\$code, 0,$A,$B,$C,$D,$E,$T);
+ &BODY_00_15(\$code, 1,$T,$A,$B,$C,$D,$E);
+ &BODY_00_15(\$code, 2,$E,$T,$A,$B,$C,$D);
+ &BODY_00_15(\$code, 3,$D,$E,$T,$A,$B,$C);
+ &BODY_00_15(\$code, 4,$C,$D,$E,$T,$A,$B);
+ &BODY_00_15(\$code, 5,$B,$C,$D,$E,$T,$A);
+ &BODY_00_15(\$code, 6,$A,$B,$C,$D,$E,$T);
+ &BODY_00_15(\$code, 7,$T,$A,$B,$C,$D,$E);
+ &BODY_00_15(\$code, 8,$E,$T,$A,$B,$C,$D);
+ &BODY_00_15(\$code, 9,$D,$E,$T,$A,$B,$C);
+ &BODY_00_15(\$code,10,$C,$D,$E,$T,$A,$B);
+ &BODY_00_15(\$code,11,$B,$C,$D,$E,$T,$A);
+ &BODY_00_15(\$code,12,$A,$B,$C,$D,$E,$T);
+ &BODY_00_15(\$code,13,$T,$A,$B,$C,$D,$E);
+ &BODY_00_15(\$code,14,$E,$T,$A,$B,$C,$D);
+ &BODY_00_15(\$code,15,$D,$E,$T,$A,$B,$C);
+
+ &BODY_16_19(\$code,16,$C,$D,$E,$T,$A,$B);
+ &BODY_16_19(\$code,17,$B,$C,$D,$E,$T,$A);
+ &BODY_16_19(\$code,18,$A,$B,$C,$D,$E,$T);
+ &BODY_16_19(\$code,19,$T,$A,$B,$C,$D,$E);
+
+ &BODY_20_39(\$code,20,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,21,$D,$E,$T,$A,$B,$C);
+ &BODY_20_39(\$code,22,$C,$D,$E,$T,$A,$B);
+ &BODY_20_39(\$code,23,$B,$C,$D,$E,$T,$A);
+ &BODY_20_39(\$code,24,$A,$B,$C,$D,$E,$T);
+ &BODY_20_39(\$code,25,$T,$A,$B,$C,$D,$E);
+ &BODY_20_39(\$code,26,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,27,$D,$E,$T,$A,$B,$C);
+ &BODY_20_39(\$code,28,$C,$D,$E,$T,$A,$B);
+ &BODY_20_39(\$code,29,$B,$C,$D,$E,$T,$A);
+ &BODY_20_39(\$code,30,$A,$B,$C,$D,$E,$T);
+ &BODY_20_39(\$code,31,$T,$A,$B,$C,$D,$E);
+ &BODY_20_39(\$code,32,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,33,$D,$E,$T,$A,$B,$C);
+ &BODY_20_39(\$code,34,$C,$D,$E,$T,$A,$B);
+ &BODY_20_39(\$code,35,$B,$C,$D,$E,$T,$A);
+ &BODY_20_39(\$code,36,$A,$B,$C,$D,$E,$T);
+ &BODY_20_39(\$code,37,$T,$A,$B,$C,$D,$E);
+ &BODY_20_39(\$code,38,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,39,$D,$E,$T,$A,$B,$C);
+
+ &BODY_40_59(\$code,40,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,41,$B,$C,$D,$E,$T,$A);
+ &BODY_40_59(\$code,42,$A,$B,$C,$D,$E,$T);
+ &BODY_40_59(\$code,43,$T,$A,$B,$C,$D,$E);
+ &BODY_40_59(\$code,44,$E,$T,$A,$B,$C,$D);
+ &BODY_40_59(\$code,45,$D,$E,$T,$A,$B,$C);
+ &BODY_40_59(\$code,46,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,47,$B,$C,$D,$E,$T,$A);
+ &BODY_40_59(\$code,48,$A,$B,$C,$D,$E,$T);
+ &BODY_40_59(\$code,49,$T,$A,$B,$C,$D,$E);
+ &BODY_40_59(\$code,50,$E,$T,$A,$B,$C,$D);
+ &BODY_40_59(\$code,51,$D,$E,$T,$A,$B,$C);
+ &BODY_40_59(\$code,52,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,53,$B,$C,$D,$E,$T,$A);
+ &BODY_40_59(\$code,54,$A,$B,$C,$D,$E,$T);
+ &BODY_40_59(\$code,55,$T,$A,$B,$C,$D,$E);
+ &BODY_40_59(\$code,56,$E,$T,$A,$B,$C,$D);
+ &BODY_40_59(\$code,57,$D,$E,$T,$A,$B,$C);
+ &BODY_40_59(\$code,58,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,59,$B,$C,$D,$E,$T,$A);
+
+ &BODY_60_79(\$code,60,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,61,$T,$A,$B,$C,$D,$E);
+ &BODY_60_79(\$code,62,$E,$T,$A,$B,$C,$D);
+ &BODY_60_79(\$code,63,$D,$E,$T,$A,$B,$C);
+ &BODY_60_79(\$code,64,$C,$D,$E,$T,$A,$B);
+ &BODY_60_79(\$code,65,$B,$C,$D,$E,$T,$A);
+ &BODY_60_79(\$code,66,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,67,$T,$A,$B,$C,$D,$E);
+ &BODY_60_79(\$code,68,$E,$T,$A,$B,$C,$D);
+ &BODY_60_79(\$code,69,$D,$E,$T,$A,$B,$C);
+ &BODY_60_79(\$code,70,$C,$D,$E,$T,$A,$B);
+ &BODY_60_79(\$code,71,$B,$C,$D,$E,$T,$A);
+ &BODY_60_79(\$code,72,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,73,$T,$A,$B,$C,$D,$E);
+ &BODY_60_79(\$code,74,$E,$T,$A,$B,$C,$D);
+ &BODY_60_79(\$code,75,$D,$E,$T,$A,$B,$C);
+ &BODY_60_79(\$code,76,$C,$D,$E,$T,$A,$B);
+ &BODY_60_79(\$code,77,$B,$C,$D,$E,$T,$A);
+ &BODY_60_79(\$code,78,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,79,$T,$A,$B,$C,$D,$E);
+
+$code.=<<___;
+{ .mmb; add $h0=$h0,$E
+ nop.m 0
+ br.ctop.dptk.many .Lhtop };;
+.Lhend:
+{ .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_asm_host_order#
+___
+
+
+$code.=<<___;
+// void sha1_block_asm_data_order(SHA_CTX *c,const void *p,size_t num);
+.global sha1_block_asm_data_order#
+.proc sha1_block_asm_data_order#
+.align 32
+sha1_block_asm_data_order:
+___
+$code.=<<___ if ($big_endian);
+{ .mmi; and r2=3,inp };;
+{ .mib; cmp.eq p6,p0=r0,r2
+(p6) br.dptk.many sha1_block_asm_host_order };;
+___
+$code.=<<___;
+ .prologue
+ .fframe 0
+ .save ar.pfs,r0
+ .save ar.lc,r3
+{ .mmi; alloc tmp1=ar.pfs,3,15,0,0
+ $ADDP tmp0=4,ctx
+ mov r3=ar.lc }
+{ .mmi; $ADDP ctx=0,ctx
+ $ADDP inp=0,inp
+ mov r2=pr };;
+tmp4=in2;
+tmp5=loc13;
+tmp6=loc14;
+ .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 };;
+
+___
+
+ &BODY_00_15(\$code, 0,$A,$B,$C,$D,$E,$T,1);
+ &BODY_00_15(\$code, 1,$T,$A,$B,$C,$D,$E,1);
+ &BODY_00_15(\$code, 2,$E,$T,$A,$B,$C,$D,1);
+ &BODY_00_15(\$code, 3,$D,$E,$T,$A,$B,$C,1);
+ &BODY_00_15(\$code, 4,$C,$D,$E,$T,$A,$B,1);
+ &BODY_00_15(\$code, 5,$B,$C,$D,$E,$T,$A,1);
+ &BODY_00_15(\$code, 6,$A,$B,$C,$D,$E,$T,1);
+ &BODY_00_15(\$code, 7,$T,$A,$B,$C,$D,$E,1);
+ &BODY_00_15(\$code, 8,$E,$T,$A,$B,$C,$D,1);
+ &BODY_00_15(\$code, 9,$D,$E,$T,$A,$B,$C,1);
+ &BODY_00_15(\$code,10,$C,$D,$E,$T,$A,$B,1);
+ &BODY_00_15(\$code,11,$B,$C,$D,$E,$T,$A,1);
+ &BODY_00_15(\$code,12,$A,$B,$C,$D,$E,$T,1);
+ &BODY_00_15(\$code,13,$T,$A,$B,$C,$D,$E,1);
+ &BODY_00_15(\$code,14,$E,$T,$A,$B,$C,$D,1);
+ &BODY_00_15(\$code,15,$D,$E,$T,$A,$B,$C,1);
+
+ &BODY_16_19(\$code,16,$C,$D,$E,$T,$A,$B);
+ &BODY_16_19(\$code,17,$B,$C,$D,$E,$T,$A);
+ &BODY_16_19(\$code,18,$A,$B,$C,$D,$E,$T);
+ &BODY_16_19(\$code,19,$T,$A,$B,$C,$D,$E);
+
+ &BODY_20_39(\$code,20,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,21,$D,$E,$T,$A,$B,$C);
+ &BODY_20_39(\$code,22,$C,$D,$E,$T,$A,$B);
+ &BODY_20_39(\$code,23,$B,$C,$D,$E,$T,$A);
+ &BODY_20_39(\$code,24,$A,$B,$C,$D,$E,$T);
+ &BODY_20_39(\$code,25,$T,$A,$B,$C,$D,$E);
+ &BODY_20_39(\$code,26,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,27,$D,$E,$T,$A,$B,$C);
+ &BODY_20_39(\$code,28,$C,$D,$E,$T,$A,$B);
+ &BODY_20_39(\$code,29,$B,$C,$D,$E,$T,$A);
+ &BODY_20_39(\$code,30,$A,$B,$C,$D,$E,$T);
+ &BODY_20_39(\$code,31,$T,$A,$B,$C,$D,$E);
+ &BODY_20_39(\$code,32,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,33,$D,$E,$T,$A,$B,$C);
+ &BODY_20_39(\$code,34,$C,$D,$E,$T,$A,$B);
+ &BODY_20_39(\$code,35,$B,$C,$D,$E,$T,$A);
+ &BODY_20_39(\$code,36,$A,$B,$C,$D,$E,$T);
+ &BODY_20_39(\$code,37,$T,$A,$B,$C,$D,$E);
+ &BODY_20_39(\$code,38,$E,$T,$A,$B,$C,$D);
+ &BODY_20_39(\$code,39,$D,$E,$T,$A,$B,$C);
+
+ &BODY_40_59(\$code,40,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,41,$B,$C,$D,$E,$T,$A);
+ &BODY_40_59(\$code,42,$A,$B,$C,$D,$E,$T);
+ &BODY_40_59(\$code,43,$T,$A,$B,$C,$D,$E);
+ &BODY_40_59(\$code,44,$E,$T,$A,$B,$C,$D);
+ &BODY_40_59(\$code,45,$D,$E,$T,$A,$B,$C);
+ &BODY_40_59(\$code,46,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,47,$B,$C,$D,$E,$T,$A);
+ &BODY_40_59(\$code,48,$A,$B,$C,$D,$E,$T);
+ &BODY_40_59(\$code,49,$T,$A,$B,$C,$D,$E);
+ &BODY_40_59(\$code,50,$E,$T,$A,$B,$C,$D);
+ &BODY_40_59(\$code,51,$D,$E,$T,$A,$B,$C);
+ &BODY_40_59(\$code,52,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,53,$B,$C,$D,$E,$T,$A);
+ &BODY_40_59(\$code,54,$A,$B,$C,$D,$E,$T);
+ &BODY_40_59(\$code,55,$T,$A,$B,$C,$D,$E);
+ &BODY_40_59(\$code,56,$E,$T,$A,$B,$C,$D);
+ &BODY_40_59(\$code,57,$D,$E,$T,$A,$B,$C);
+ &BODY_40_59(\$code,58,$C,$D,$E,$T,$A,$B);
+ &BODY_40_59(\$code,59,$B,$C,$D,$E,$T,$A);
+
+ &BODY_60_79(\$code,60,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,61,$T,$A,$B,$C,$D,$E);
+ &BODY_60_79(\$code,62,$E,$T,$A,$B,$C,$D);
+ &BODY_60_79(\$code,63,$D,$E,$T,$A,$B,$C);
+ &BODY_60_79(\$code,64,$C,$D,$E,$T,$A,$B);
+ &BODY_60_79(\$code,65,$B,$C,$D,$E,$T,$A);
+ &BODY_60_79(\$code,66,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,67,$T,$A,$B,$C,$D,$E);
+ &BODY_60_79(\$code,68,$E,$T,$A,$B,$C,$D);
+ &BODY_60_79(\$code,69,$D,$E,$T,$A,$B,$C);
+ &BODY_60_79(\$code,70,$C,$D,$E,$T,$A,$B);
+ &BODY_60_79(\$code,71,$B,$C,$D,$E,$T,$A);
+ &BODY_60_79(\$code,72,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,73,$T,$A,$B,$C,$D,$E);
+ &BODY_60_79(\$code,74,$E,$T,$A,$B,$C,$D);
+ &BODY_60_79(\$code,75,$D,$E,$T,$A,$B,$C);
+ &BODY_60_79(\$code,76,$C,$D,$E,$T,$A,$B);
+ &BODY_60_79(\$code,77,$B,$C,$D,$E,$T,$A);
+ &BODY_60_79(\$code,78,$A,$B,$C,$D,$E,$T);
+ &BODY_60_79(\$code,79,$T,$A,$B,$C,$D,$E);
+
+$code.=<<___;
+{ .mmb; add $h0=$h0,$E
+ nop.m 0
+ 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_asm_data_order#
+___
+
+print $code;
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
new file mode 100644
index 0000000000..087e8783a8
--- /dev/null
+++ b/crypto/x509/x509_vpm.c
@@ -0,0 +1,400 @@
+/* x509_vpm.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) 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->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 (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)
+ {
+ to->inh_flags |= X509_VP_FLAG_DEFAULT;
+ return X509_VERIFY_PARAM_inherit(to, from);
+ }
+
+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_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 */
+ 9, /* depth */
+ NULL /* policies */
+ },
+ {
+ "pkcs7", /* SSL/TLS client 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 void *pa, const void *pb)
+ {
+ const X509_VERIFY_PARAM *a = pa, *b = pb;
+ return strcmp(a->name, b->name);
+ }
+
+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);
+ 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 (const X509_VERIFY_PARAM *) OBJ_bsearch((char *)&pm,
+ (char *)&default_table,
+ sizeof(default_table)/sizeof(X509_VERIFY_PARAM),
+ sizeof(X509_VERIFY_PARAM),
+ table_cmp);
+ }
+
+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/crypto/x509v3/v3_pci.c b/crypto/x509v3/v3_pci.c
new file mode 100644
index 0000000000..b32d968619
--- /dev/null
+++ b/crypto/x509v3/v3_pci.c
@@ -0,0 +1,313 @@
+/* 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);
+
+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_R2I_PCI,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ if (!(*language = OBJ_txt2obj(val->value, 0)))
+ {
+ X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ }
+ else if (strcmp(val->name, "pathlen") == 0)
+ {
+ if (*pathlen)
+ {
+ X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED);
+ X509V3_conf_err(val);
+ return 0;
+ }
+ if (!X509V3_get_value_int(val, pathlen))
+ {
+ X509V3err(X509V3_F_R2I_PCI,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_R2I_PCI,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) 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 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_R2I_PCI,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';
+ }
+
+ if (n < 0)
+ {
+ X509V3err(X509V3_F_R2I_PCI,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
+ {
+ X509V3err(X509V3_F_R2I_PCI,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+ X509V3_conf_err(val);
+ goto err;
+ }
+ if (!tmp_data)
+ {
+ X509V3err(X509V3_F_R2I_PCI,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 = PROXY_POLICY_new();
+ if (!pci->proxyPolicy)
+ {
+ 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 && pci->proxyPolicy)
+ {
+ PROXY_POLICY_free(pci->proxyPolicy);
+ pci->proxyPolicy = 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/crypto/x509v3/v3_pcia.c b/crypto/x509v3/v3_pcia.c
new file mode 100644
index 0000000000..bb362e0e5a
--- /dev/null
+++ b/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/crypto/x86cpuid.pl b/crypto/x86cpuid.pl
new file mode 100644
index 0000000000..894c49c0a3
--- /dev/null
+++ b/crypto/x86cpuid.pl
@@ -0,0 +1,77 @@
+#!/usr/bin/env perl
+
+push(@INC,"perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"x86cpuid");
+
+&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");
+ &bt ("ecx",21);
+ &jnc (&label("nocpuid"));
+ &mov ("eax",1);
+ &cpuid ();
+&set_label("nocpuid");
+ &mov ("eax","edx");
+ &mov ("edx","ecx");
+&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");
+
+&initseg("OPENSSL_cpuid_setup");
+
+&asm_finish();
diff --git a/doc/apps/errstr.pod b/doc/apps/errstr.pod
new file mode 100644
index 0000000000..b3c6ccfc9c
--- /dev/null
+++ b/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/doc/apps/x509v3_config.pod b/doc/apps/x509v3_config.pod
new file mode 100644
index 0000000000..09954693a3
--- /dev/null
+++ b/doc/apps/x509v3_config.pod
@@ -0,0 +1,456 @@
+=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<ARBITRART 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
+ASN1_generate_nconf() 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 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.
+
+Examples:
+
+ crlDistributionPoints=URI:http://myhost.com/myca.crl
+ crlDistributionPoints=URI:http://my.com/my.crl,URI:http://oth.com/my.crl
+
+=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
+
+=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 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 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, name constraints, 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)>
+
+
+=cut
diff --git a/doc/crypto/OPENSSL_ia32cap.pod b/doc/crypto/OPENSSL_ia32cap.pod
new file mode 100644
index 0000000000..ec6b655c17
--- /dev/null
+++ b/doc/crypto/OPENSSL_ia32cap.pod
@@ -0,0 +1,35 @@
+=pod
+
+=head1 NAME
+
+OPENSSL_ia32cap
+
+=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 three bits are
+significant, namely bit #28 denoting Hyperthreading, which is used to
+distinguish Intel P4 core, bit #26 denoting SSE2 support, and bit #4
+denoting presence of Time-Stamp Counter. Clearing bit #26 at run-time
+for example 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. 'env OPENSSL_ia32cap=0x10 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/test/P1ss.cnf b/test/P1ss.cnf
new file mode 100644
index 0000000000..876a0d35f8
--- /dev/null
+++ b/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 = 512
+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/test/P2ss.cnf b/test/P2ss.cnf
new file mode 100644
index 0000000000..373a87e7c2
--- /dev/null
+++ b/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 = 512
+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/test/testsslproxy b/test/testsslproxy
new file mode 100644
index 0000000000..70cf12342d
--- /dev/null
+++ b/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_auth $auth -proxy_cond $cond"
+ if [ $? = 3 ]; then exit 1; fi
+ done
+done
diff --git a/util/extract-section.pl b/util/extract-section.pl
new file mode 100644
index 0000000000..7a0ba4f69a
--- /dev/null
+++ b/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/util/opensslwrap.sh b/util/opensslwrap.sh
new file mode 100755
index 0000000000..91d29e2b87
--- /dev/null
+++ b/util/opensslwrap.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+HERE="`echo $0 | sed -e 's|[^/]*$||'`"
+OPENSSL="${HERE}../apps/openssl"
+
+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/util/shlib_wrap.sh b/util/shlib_wrap.sh
new file mode 100755
index 0000000000..dc5f5b1ce4
--- /dev/null
+++ b/util/shlib_wrap.sh
@@ -0,0 +1,70 @@
+#!/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*)
+ [ -n "$LD_LIBRARY_PATH_64" ] && rld_var=LD_LIBRARY_PATH_64
+ ;;
+ *ELF\ N32*MIPS*)
+ [ -n "$LD_LIBRARYN32_PATH" ] && rld_var=LD_LIBRARYN32_PATH
+ _RLDN32_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLDN32_LIST
+ ;;
+ *ELF\ 64*MIPS*)
+ [ -n "$LD_LIBRARY64_PATH" ] && rld_var=LD_LIBRARY64_PATH
+ _RLD64_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT"; export _RLD64_LIST
+ ;;
+ esac
+ eval $rld_var=\"${THERE}:'$'$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" ]; 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) LD_PRELOAD="$LIBCRYPTOSO:$LIBSSLSO" ;; # *BSD
+ *) LD_PRELOAD="$LIBCRYPTOSO $LIBSSLSO" ;; # SunOS, Linux, ELF HP-UX
+ esac
+ _RLD_LIST="$LIBCRYPTOSO:$LIBSSLSO:DEFAULT" # Tru64, o32 IRIX
+ export LD_PRELOAD _RLD_LIST
+fi
+
+exec "$@"