diff options
author | cvs2svn <cvs2svn> | 2005-02-06 13:15:22 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn> | 2005-02-06 13:15:22 +0000 |
commit | afcff52ef7256809a89a48347c7185644f56bb25 (patch) | |
tree | ae2eb4632cc8ebe68f337a6b3b0c7faa6b8721f0 | |
parent | fc0a2da735e00434f5e15f7cea6ec20da9e629f5 (diff) | |
parent | de4ab1e6290d23bf8732f7ad65f5471d94e2dd3d (diff) | |
download | openssl-new-afcff52ef7256809a89a48347c7185644f56bb25.tar.gz |
This commit was manufactured by cvs2svn to create branch 'BRANCH_VMS_64BIT'.
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(¶m->purpose, purpose); + } + +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) + { + return X509_TRUST_set(¶m->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 "$@" |