You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by rl...@apache.org on 2016/09/07 02:57:39 UTC

[01/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Repository: incubator-hawq
Updated Branches:
  refs/heads/master 327863331 -> 801100edd


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql b/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
new file mode 100644
index 0000000..cc82420
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql
@@ -0,0 +1,548 @@
+--
+-- PGP Public Key Encryption
+--
+
+-- As most of the low-level stuff is tested in symmetric key
+-- tests, here's only public-key specific tests
+
+create table keytbl (
+	id int4,
+	name text,
+	pubkey text,
+	seckey text
+);
+create table encdata (
+	id int4,
+	data text
+);
+
+insert into keytbl (id, name, pubkey, seckey)
+values (1, 'elg1024', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
+MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
+AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
+ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
+sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
++h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
+6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
+k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
+iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
+ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
+=RWci
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQAAAnj4i4st+s+C6
+WKTIDcL1Iy0Saq8lCp60H0VsZ2FtYWwgMTAyNCA8dGVzdEBleGFtcGxlLm9yZz6I
+XgQTEQIAHgUCQsghSAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAcKbwNGBdz
+ZDrbAJ9cp6AsjOhiLxwznsMJheGf4xkH8wCfUPjMCLm4tAEnyYn2hDNt7CB8B6Kd
+ATEEQsghShAEAIeUjW2yTALCfrEG3FhM3ZLvAHWAec2O0Mn/RDr59IN/W8wDYcZp
+m+oG0ZUDdIqMppQ8K2kylAH7gmYDXIP9D7MRRm/Zw3L4yFfKnVaZ6tT7szBbgW5h
+iOsHoOz49NXZT4jtMLdZS1/krm5Lam2MSPod9XN0Q2asY/igIMUfGDRjAAMGA/sE
+LNh3tWefqeDkoDBEYjcxdGnGVGJnNHvv/eoHy9H7dyD/kkhaOoRAa5ClYWSqD0kk
+a+SqTWhKG4XcbJyo1GsP6sqGhXDTM2+LBZPMKuVJQpEfoe9ruob/BbpXglfEiVE9
+VNiY7ZVyUdj3svYn4fK2X7ue1G3cHR2tL4lnOA4pYQAA9030E4u2ZKOfJBpUM+EM
+m9VmsGjaQZV4teB0R/q3W8sRIYhJBBgRAgAJBQJCyCFKAhsMAAoJEBwpvA0YF3Nk
+7a8AniFFotw1x2X+oryu3Q3nNtmxoKHpAJ9HU7jw7ydg33dI9J8gVkrmsSZ2/w==
+=nvqq
+-----END PGP PRIVATE KEY BLOCK-----
+');
+
+insert into keytbl (id, name, pubkey, seckey)
+values (2, 'elg2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
+vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
+5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
+RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
+8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
+Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
+J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
+T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
+0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6a7QjRWxnYW1hbCAy
+MDQ4IDx0ZXN0MjA0OEBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgiCgIbAwYLCQgH
+AwIDFQIDAxYCAQIeAQIXgAAKCRBI6c1W/qZo29PDAKCG724enIxRog1j+aeCp/uq
+or6mbwCePuKy2/1kD1FvnhkZ/R5fpm+pdm25Ag0EQsgiIhAIAJI3Gb2Ehtz1taQ9
+AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMX
+MhoWyw8ZF5Zs1mLIjFGVorePrm94N3MNPWM7x9M36bHUjx0vCZKFIhcGY1g+htE/
+QweaJzNVeA5z4qZmik41FbQyQSyHa3bOkTZu++/U6ghP+iDp5UDBjMTkVyqITUVN
+gC+MR+da/I60irBVhue7younh4ovF+CrVDQJC06HZl6CAJJyA81SmRfi+dmKbbjZ
+LF6rhz0norPjISJvkIqvdtM4VPBKI5wpgwCzpEqjuiKrAVujRT68zvBvJ4aVqb11
+k5QdJscAAwUH/jVJh0HbWAoiFTe+NvohfrA8vPcD0rtU3Y+siiqrabotnxJd2NuC
+bxghJYGfNtnx0KDjFbCRKJVeTFok4UnuVYhXdH/c6i0/rCTNdeW2D6pmR4GfBozR
+Pw/ARf+jONawGLyUj7uq13iquwMSE7VyNuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0R
+QsetMq/iNBWraayKZnWUd+eQqNzE+NUo7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiF
+Z1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qunfGW00ZMMTCWabg0ZgxPzMfMeIcm6525A
+Yn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/RdWaISQQYEQIACQUCQsgiIgIbDAAKCRBI
+6c1W/qZo25ZSAJ98WTrtl2HiX8ZqZq95v1+9cHtZPQCfZDoWQPybkNescLmXC7q5
+1kNTmEU=
+=8QM5
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
+vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
+5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
+RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
+8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
+Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
+J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
+T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
+0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6awAAn2F+iNBElfJS
+8azqO/kEiIfpqu6/DQG0I0VsZ2FtYWwgMjA0OCA8dGVzdDIwNDhAZXhhbXBsZS5v
+cmc+iF0EExECAB4FAkLIIgoCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQSOnN
+Vv6maNvTwwCYkpcJmpl3aHCQdGomz7dFohDgjgCgiThZt2xTEi6GhBB1vuhk+f55
+n3+dAj0EQsgiIhAIAJI3Gb2Ehtz1taQ9AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D
+29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMXMhoWyw8ZF5Zs1mLIjFGVorePrm94N3MN
+PWM7x9M36bHUjx0vCZKFIhcGY1g+htE/QweaJzNVeA5z4qZmik41FbQyQSyHa3bO
+kTZu++/U6ghP+iDp5UDBjMTkVyqITUVNgC+MR+da/I60irBVhue7younh4ovF+Cr
+VDQJC06HZl6CAJJyA81SmRfi+dmKbbjZLF6rhz0norPjISJvkIqvdtM4VPBKI5wp
+gwCzpEqjuiKrAVujRT68zvBvJ4aVqb11k5QdJscAAwUH/jVJh0HbWAoiFTe+Nvoh
+frA8vPcD0rtU3Y+siiqrabotnxJd2NuCbxghJYGfNtnx0KDjFbCRKJVeTFok4Unu
+VYhXdH/c6i0/rCTNdeW2D6pmR4GfBozRPw/ARf+jONawGLyUj7uq13iquwMSE7Vy
+NuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0RQsetMq/iNBWraayKZnWUd+eQqNzE+NUo
+7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiFZ1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qun
+fGW00ZMMTCWabg0ZgxPzMfMeIcm6525AYn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/R
+dWYAAVQKFPXbRaxbdArwRVXMzSD3qj/+VwwhwEDt8zmBGnlBfwVdkjQQrDUMmV1S
+EwyISQQYEQIACQUCQsgiIgIbDAAKCRBI6c1W/qZo25ZSAJ4sgUfHTVsG/x3p3fcM
+3b5R86qKEACggYKSwPWCs0YVRHOWqZY0pnHtLH8=
+=3Dgk
+-----END PGP PRIVATE KEY BLOCK-----
+');
+
+insert into keytbl (id, name, pubkey, seckey)
+values (3, 'elg4096', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
+05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
+2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
+cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
+SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
+18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
+7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
+q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
+uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk27QjRWxnYW1hbCA0
+MDk2IDx0ZXN0NDA5NkBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgjvAIbAwYLCQgH
+AwIDFQIDAxYCAQIeAQIXgAAKCRBj+HX2P2d0oAEDAJ9lI+CNmb42z3+a6TnVusM6
+FI7oLwCfUwA1zEcRdsT3nIkoYh0iKxFSDFW5BA0EQsgkdhAQAJQbLXlgcJ/jq+Xh
+Eujb77/eeftFJObNIRYD9fmJ7HFIXbUcknEpbs+cRH/nrj5dGSY3OT3jCXOUtvec
+sCoX/CpZWL0oqDjAiZtNSFiulw5Gav4gHYkWKgKdSo+2rkavEPqKIVHvMeXaJtGT
+d7v/AmL/P8T7gls93o5WFBOLtPbDvWqaKRy2U5TAhl1laiM0vGALRVjvSCgnGw9g
+FpSnXbO3AfenUSjDzZujfGLHtU44ixHSS/D4DepiF3YaYLsN4CBqZRv6FbMZD5W3
+DnJY4kS1kH0MzdcF19TlcZ3itTCcGIt1tMKf84mccPoqdMzH7vumBGTeFEly5Afp
+9berJcirqh2fzlunN0GS02z6SGWnjTbDlkNDxuxPSBbpcpNyD3jpYAUqSwRsZ/+5
+zkzcbGtDmvy9sJ5lAXkxGoIoQ1tEVX/LOHnh2NQHK8ourVOnr7MS0nozssITZJ5E
+XqtHiREjiYEuPyZiVZKJHLWuYYaF+n40znnz3sJuXFRreHhHbbvRdlYUU5mJV+XZ
+BLgKuS33NdpGeMIngnCc/9IQ6OZb6ixc94kbkd3w2PVr8CbKlu/IHTjWOO2mAo+D
++OydlYl23FiM3KOyMP1HcEOJMB/nwkMtrvd+522Lu9n77ktKfot9IPrQDIQTyXjR
+3pCOFtCOBnk2tJHMPoG9jn9ah/LHAAMHEACDZ5I/MHGfmiKg2hrmqBu2J2j/deC8
+CpwcyDH1ovQ0gHvb9ESa+CVRU2Wdy2CD7Q9SmtMverB5eneL418iPVRcQdwRmQ2y
+IH4udlBa6ce9HTUCaecAZ4/tYBnaC0Av/9l9tz14eYcwRMDpB+bnkhgF+PZ1KAfD
+9wcY2aHbtsf3lZBc5h4owPJkxpe/BNzuJxW3q4VpSbLsZhwnCZ2wg7DRwP44wFIk
+00ptmoBY59gsU6I40XtzrF8JDr0cA57xND5RY21Z8lnnYRE1Tc8h5REps9ZIxW3/
+yl91404bPLqxczpUHQAMSTAmBaStPYX1nS51uofOhLs5SKPCUmxfGKIOhsD0oLUn
+78DnkONVGeXzBibSwwtbgfMzee4G8wSUfJ7w8WXz1TyanaGLnJ+DuKASSOrFoBCD
+HEDuWZWgSL74NOQupFRk0gxOPmqU94Y8HziQWma/cETbmD83q8rxN+GM2oBxQkQG
+xcbqMTHE7aVhV3tymbSWVaYhww3oIwsZS9oUIi1DnPEowS6CpVRrwdvLjLJnJzzV
+O3AFPn9eZ1Q7R1tNx+zZ4OOfhvI/OlRJ3HBx2L53embkbdY9gFYCCdTjPyjKoDIx
+kALgCajjCYMNUsAKNSd6mMCQ8TtvukSzkZS1RGKP27ohsdnzIVsiEAbxDMMcI4k1
+ul0LExUTCXSjeIhJBBgRAgAJBQJCyCR2AhsMAAoJEGP4dfY/Z3Sg19sAn0NDS8pb
+qrMpQAxSb7zRTmcXEFd9AJ435H0ttP/NhLHXC9ezgbCMmpXMOQ==
+=kRxT
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
+05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
+2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
+cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
+SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
+18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
+7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
+q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
+uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk2wAAoJCUNy6awTkw
+XfbLbpqh0fvDst7jDLa0I0VsZ2FtYWwgNDA5NiA8dGVzdDQwOTZAZXhhbXBsZS5v
+cmc+iF4EExECAB4FAkLII7wCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQY/h1
+9j9ndKABAwCeNEOVK87EzXYbtxYBsnjrUI948NIAn2+f3BXiBFDV5NvqPwIZ0m77
+Fwy4nQRMBELIJHYQEACUGy15YHCf46vl4RLo2++/3nn7RSTmzSEWA/X5iexxSF21
+HJJxKW7PnER/564+XRkmNzk94wlzlLb3nLAqF/wqWVi9KKg4wImbTUhYrpcORmr+
+IB2JFioCnUqPtq5GrxD6iiFR7zHl2ibRk3e7/wJi/z/E+4JbPd6OVhQTi7T2w71q
+mikctlOUwIZdZWojNLxgC0VY70goJxsPYBaUp12ztwH3p1Eow82bo3xix7VOOIsR
+0kvw+A3qYhd2GmC7DeAgamUb+hWzGQ+Vtw5yWOJEtZB9DM3XBdfU5XGd4rUwnBiL
+dbTCn/OJnHD6KnTMx+77pgRk3hRJcuQH6fW3qyXIq6odn85bpzdBktNs+khlp402
+w5ZDQ8bsT0gW6XKTcg946WAFKksEbGf/uc5M3GxrQ5r8vbCeZQF5MRqCKENbRFV/
+yzh54djUByvKLq1Tp6+zEtJ6M7LCE2SeRF6rR4kRI4mBLj8mYlWSiRy1rmGGhfp+
+NM55897CblxUa3h4R2270XZWFFOZiVfl2QS4Crkt9zXaRnjCJ4JwnP/SEOjmW+os
+XPeJG5Hd8Nj1a/AmypbvyB041jjtpgKPg/jsnZWJdtxYjNyjsjD9R3BDiTAf58JD
+La73fudti7vZ++5LSn6LfSD60AyEE8l40d6QjhbQjgZ5NrSRzD6BvY5/WofyxwAD
+BxAAg2eSPzBxn5oioNoa5qgbtido/3XgvAqcHMgx9aL0NIB72/REmvglUVNlnctg
+g+0PUprTL3qweXp3i+NfIj1UXEHcEZkNsiB+LnZQWunHvR01AmnnAGeP7WAZ2gtA
+L//Zfbc9eHmHMETA6Qfm55IYBfj2dSgHw/cHGNmh27bH95WQXOYeKMDyZMaXvwTc
+7icVt6uFaUmy7GYcJwmdsIOw0cD+OMBSJNNKbZqAWOfYLFOiONF7c6xfCQ69HAOe
+8TQ+UWNtWfJZ52ERNU3PIeURKbPWSMVt/8pfdeNOGzy6sXM6VB0ADEkwJgWkrT2F
+9Z0udbqHzoS7OUijwlJsXxiiDobA9KC1J+/A55DjVRnl8wYm0sMLW4HzM3nuBvME
+lHye8PFl89U8mp2hi5yfg7igEkjqxaAQgxxA7lmVoEi++DTkLqRUZNIMTj5qlPeG
+PB84kFpmv3BE25g/N6vK8TfhjNqAcUJEBsXG6jExxO2lYVd7cpm0llWmIcMN6CML
+GUvaFCItQ5zxKMEugqVUa8Hby4yyZyc81TtwBT5/XmdUO0dbTcfs2eDjn4byPzpU
+Sdxwcdi+d3pm5G3WPYBWAgnU4z8oyqAyMZAC4Amo4wmDDVLACjUnepjAkPE7b7pE
+s5GUtURij9u6IbHZ8yFbIhAG8QzDHCOJNbpdCxMVEwl0o3gAAckBdfKuasiNUn5G
+L5XRnSvaOFzftr8zteOlZChCSNvzH5k+i1j7RJbWq06OeKRywPzjfjgM2MvRzI43
+ICeISQQYEQIACQUCQsgkdgIbDAAKCRBj+HX2P2d0oNfbAJ9+G3SeXrk+dWwo9EGi
+hqMi2GVTsgCfeoQJPsc8FLYUgfymc/3xqAVLUtg=
+=Gjq6
+-----END PGP PRIVATE KEY BLOCK-----
+');
+
+insert into keytbl (id, name, pubkey, seckey)
+values (4, 'rsa2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
+ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
+55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
+5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
+MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
+R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYptB5SU0EgMjA0OCA8cnNhMjA0
+OEBleGFtcGxlLm9yZz6JATQEEwECAB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgEC
+HgECF4AACgkQnc+OnJvTHyQqHwf8DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liR
+nrLuVlLBpdO6CWmMUzfKRvyZlx54GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzw
+bLZyM5Gb3lsE/FEmE7Dxw/0Utf59uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDP
+D3dnU4uzKPhMcjnSN00pzjusP7C9NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv
+9bgGWopumlOkt8Zu5YG6+CtTbJXprPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhv
+S3NZKoJ/1DrGgoDAu1mGkM4KvLAxfDs/qQ9dZhtEmDbKPLTVEA==
+=lR4n
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQOWBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
+ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
+55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
+5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
+MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
+R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYpAAf/QZsrrz0c7dgWwGqMIpw6
+fP+/lLa74+fa2CFRWtYowEiKsfDg/wN7Ua07036dNhPa8aZPsU6SRzm5PybKOURe
+D9pNt0FxJkX0j5pCWfjSJgTbc1rCdqZ/oyBk/U6pQtf//zfw3PbDl7I8TC6GOt2w
+5NgcXdsWHP7LAmPctOVUyzFsenevR0MFTHkMbmKI1HpFm8XN/e1Fl+qIAD+OagTF
+5B32VvpoJtkh5nxnIuToNJsa9Iy7F9MM2CeFOyTMihMcjXKBBUaAYoF115irBvqu
+7N/qWmzqLg8yxBZ56mh6meCF3+67VA2y7fL8rhw2QuqgLg1JFlKAVL+9crCSrn//
+GQQA1kT7FytW6BNOffblFYZkrJer3icoRDqa/ljgH/yVaWoVT1igy0E9XzYO7MwP
+2usj/resLy0NC1qCthk51cZ/wthooMl88e5Wb4l5FYwBEac7muSBTo4W8cAH1hFj
+TWL6XAGvEzGX3Mt9pn8uYGlQLZAhJoNCAU2EOCbN1PchDvsEAOWNKYesuUVk8+sQ
+St0NDNhd9BWtTWTHkCZb1dKC3JTfr9PqkTBLrWFbYjkOtvdPAW7FDaXXXZfdH1jH
+WfwP3Q+I6sqgSaWpCS4dBAns3/RVtO7czVgyIwma04iIvJqderYrfvkUq95KfwP2
+V8wXkhrPPPxyrg5y3wQlpY2jb5RBBAC17SK1ms+DBtck4vpdjp3SJ32SbyC/DU30
+89Q12j74S7Zdu1qZlKnvy3kWPYX/hMuSzGZ+mLVJNFEqH2X01aFzppYz0hdI9PGB
+9tTFEqZWQL9ZkXfjc79Cgnt12pNukRbtw0N/kyutOdIFHVT79wVAd+powqziXJsC
+Kc+4xjwSCkZitB5SU0EgMjA0OCA8cnNhMjA0OEBleGFtcGxlLm9yZz6JATQEEwEC
+AB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQnc+OnJvTHyQqHwf8
+DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liRnrLuVlLBpdO6CWmMUzfKRvyZlx54
+GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzwbLZyM5Gb3lsE/FEmE7Dxw/0Utf59
+uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDPD3dnU4uzKPhMcjnSN00pzjusP7C9
+NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv9bgGWopumlOkt8Zu5YG6+CtTbJXp
+rPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhvS3NZKoJ/1DrGgoDAu1mGkM4KvLAx
+fDs/qQ9dZhtEmDbKPLTVEA==
+=WKAv
+-----END PGP PRIVATE KEY BLOCK-----
+');
+
+insert into keytbl (id, name, pubkey, seckey)
+values (5, 'psw-elg1024', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
+MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
+AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
+ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
+sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
++h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
+6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
+k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
+iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
+ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
+=RWci
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQHpBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQP4HAwImKZ5q2QwT
+D2DDAY/IQBjes7WgqZeacfLPDoB8ecD/KLoSCH6Z3etvbPHSOKiazxoJ962Ix74H
+ZAE6ZbMTtl5dZW1ptB9FbGdhbWFsIDEwMjQgPHRlc3RAZXhhbXBsZS5vcmc+iF4E
+ExECAB4FAkLIIUgCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQHCm8DRgXc2Q6
+2wCfXKegLIzoYi8cM57DCYXhn+MZB/MAn1D4zAi5uLQBJ8mJ9oQzbewgfAeinQFf
+BELIIUoQBACHlI1tskwCwn6xBtxYTN2S7wB1gHnNjtDJ/0Q6+fSDf1vMA2HGaZvq
+BtGVA3SKjKaUPCtpMpQB+4JmA1yD/Q+zEUZv2cNy+MhXyp1WmerU+7MwW4FuYYjr
+B6Ds+PTV2U+I7TC3WUtf5K5uS2ptjEj6HfVzdENmrGP4oCDFHxg0YwADBgP7BCzY
+d7Vnn6ng5KAwRGI3MXRpxlRiZzR77/3qB8vR+3cg/5JIWjqEQGuQpWFkqg9JJGvk
+qk1oShuF3GycqNRrD+rKhoVw0zNviwWTzCrlSUKRH6Hva7qG/wW6V4JXxIlRPVTY
+mO2VclHY97L2J+Hytl+7ntRt3B0drS+JZzgOKWH+BwMCJimeatkMEw9gRkFjt4Xa
+9rX8awMBE5+vVcGKv/DNiCvJnlYvSdCj8VfuHsYFliiJo6u17NJon+K43e3yvDNk
+f631VOVanGEz7TyqOkWQiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCe
+IUWi3DXHZf6ivK7dDec22bGgoekAn0dTuPDvJ2Dfd0j0nyBWSuaxJnb/
+=SNvr
+-----END PGP PRIVATE KEY BLOCK-----
+');
+
+insert into keytbl (id, name, pubkey, seckey)
+values (6, 'rsaenc2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz
+YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8
+JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw
++IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku
+UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ
+RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8
+0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE
+QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX
+z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK
+lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE
+FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U
+rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF
+JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ
+yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0
+WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg
+w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X
+dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro
+PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh
+CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=pwU2
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQOWBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYpAAf9GuKpxrXp267eSPw9ZeSw
+Ik6ob1I0MHbhhHeaXQnF0SuOViJ1+Bs74hUB3/F5fqrnjVLIS/ysYzegYpbpXOIa
+MZwYcp2e+dpmVb7tkGQgzXH0igGtBQBqoSUVq9mG2XKPVh2JmiYgOH6GrHSGmnCq
+GCgEK4ezSomB/3OtPFSjAxOlSw6dXSkapSxW3pEGvCdaWd9p8yl4rSpGsZEErPPL
+uSbZZrHtWfgq5UXdPeE1UnMlBcvSruvpN4qgWMgSMs4d2lXvzXJLcht/nryP+atT
+H1gwnRmlDCVv5BeJepKo3ORJDvcPlXkJPhqS9If3BhTqt6QgQEFI4aIYYZOZpZoi
+2QQA2Zckzktmsc1MS04zS9gm1CbxM9d2KK8EOlh7fycRQhYYqqavhTBH2MgEp+Dd
+ZtuEN5saNDe9x/fwi2ok1Bq6luGMWPZU/nZe7fxadzwfliy/qPzStWFW3vY9mMLu
+6uEqgjin/lf4YrAswXDZaEc5e4GuNgGfwr27hpjxE1jg3PsEAPMqXEOMT2yh+yRu
+DlLRbFhYOI4aUHY2CGoQQONnwv2O5gFvmOcPlg3J5lvnwlOYCx0c3bDxAtHyjPJq
+FAZqcJBaB9RDhKHwlWDrbx/6FPH2SuKE+u4msIhPFin4V3FAP+yTem/TKrdnaWy6
+EUrhCWTXVRTijBaCudfjFd/ipHZbA/0dv7UAcoWK6kiVLzyE+jOvtN+ZxTzxq7CW
+mlFPgAC966hgJmz9IXqadtMgPAoL3PK9q1DbPM3JhsQcJrNzTJqZrdN1/kPU0HHa
++aof1BVy3wSvp2mXgaRUULStyhUIyBRM6hAYp3/MoWEYn/bwr+zQkIU8Zsk6OsZ6
+q1xE3cowrUWFtCVSU0EgMjA0OCBFbmMgPHJzYTIwNDhlbmNAZXhhbXBsZS5vcmc+
+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEMiZ6pNE
+GVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8JCaxHa31wH3PKqGtq2M+cpb2rXf7
+gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw+IkhihEb5bWxQBNj+3zAFs1YX6v2
+HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzkuUOhcgfpBgIt3Q+MpT6M2+OIF7lVf
+Sb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQRJ6DWH61F8fFIDJg1z+A/Obx4fqX
+6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO80g/oVYBbuvOYedffDBeQarhERZ5W
+2TnIE+nqY61YOLBqosliygdZTXULzNidA5YEQuvaugEIAOuCJZdkzORA6e1lr81L
+nr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPXz1YIrMTu+1rMIiy10IWbA6zgMTpz
+PhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfKlAXIxJurCHXTbEa+YvPdn76vJ3Hs
+XOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zEFZcAoKbFqAAjDLEai64SoOFh0W3C
+sD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9UrHlolqYNhYze/uRLyfnUx9PN4r/G
+hEzauyDMV0smo91uB3aewPft+eCpmeWnu0PFJVK4xyRmhIq2rVCw16a1pBJirvGM
++y0ABikAB/oC3z7lv6sVg+ngjbpWy9lZu2/ECZ9FqViVz7bUkjfvSuowgpncryLW
+4EpVV4U6mMSgU6kAi5VGT/BvYGSAtnqDWGiPs7Kk+h4Adz74bEAXzU280pNBtSfX
+tGvzlS4a376KzYFSCJDRBdMebEhJMbY0wQmR8lTZu5JSUI4YYEuN0c7ckdsw8w42
+QWTLonG8HC6h8UPKS0EAcaCo7tFubMIesU6cWuTYucsHE+wjbADjuSNX968qczNe
+NoL2BUznXOQoPu6HQO4/8cr7ib+VQkB2bHQcMoZazPUStIID1e4CL4XcxfuAmT8o
+3XDvMLgVqNp5W2f8Mzmk3/DbtsLXLOv5BADsCzQpseC8ikSYJC72hcon1wlUmGeH
+3qgGiiHhYXFa18xgI5juoO8DaWno0rPPlgr36Y8mSB5qjYHMXwjKnKyUmt11H+hU
++6uk4hq3Rjd8l+vfuOSr1xoTrtBUg9Rwfw6JVo0DC+8CWg4oBWsLXVM6KQXPFdJs
+8kyFQplR/iP1XQQA/2tbDANjAYGNNDjJO9/0kEnSAUyYMasFJDrA2q17J5CroVQw
+QpMmWwdDkRANUVPKnWHS5sS65BRc7UytKe2f3A3ZInGXJIK2Hl+TzapWYcYxql+4
+ol5mEDDMDbhEE8Wmj9KyB6iifdLI0K+yxNb9T4Jpj3J18+St+G8+9AcFcBEEAM1b
+M9C+/05cnV8gjcByqH9M9ypo8fzPvMKVXWwCLQXpaL50QIkzLURkiMoEWrCdELaA
+sVPotRzePTIQ1ooLeDxd1gRnDqjZiIR0kwmv6vq8tfzY96O2ZbGWFI5eth89aWEJ
+WB8AR3zYcXpwJLwPuhXW2/NlZF0bclJ3jNzAfTIeQmeJAR8EGAECAAkFAkLr2roC
+GwwACgkQyJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+
+1iqYE0B0WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwar
+ANhHxkWgw/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx
+2eVM1k+XdmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOy
+la+wJdroPYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CC
+hbt6LhKhCLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=UKh3
+-----END PGP PRIVATE KEY BLOCK-----
+');
+
+
+-- elg1024 / aes128
+insert into encdata (id, data) values (1, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEOA9k2z2S7c/RmEAQAgVWW0DeLrZ+1thWJGBPp2WRFL9HeNqqWHbKJCXJbz1Uy
+faUY7yxVvG5Eutmo+JMiY3mg23/DgVVXHQZsTWpGvGM6djgUNGKUjZDbW6Nog7Mr
+e78IywattCOmgUP9vIwwg3OVjuDCN/nVirGQFnXpJBc8DzWqDMWRWDy1M0ZsK7AD
+/2JTosSFxUdpON0DKtIY3GLzmh6Nk3iV0g8VgJKUBT1rhCXuMDj3snm//EMm7hTY
+PlnObq4mIhgz8NqprmhooxnU0Kapofb3P3wCHPpU14zxhXY8iKO/3JhBq2uFcx4X
+uBMwkW4AdNxY/mzJZELteTL8Tr0s7PISk+owb4URpG3n0jsBc0CVULxrjh5Ejkdw
+wCM195J6+KbQxOOFQ0b3uOVvv4dEgd/hRERCOq5EPaFhlHegyYJ7YO842vnSDA==
+=PABx
+-----END PGP MESSAGE-----
+');
+
+-- elg2048 / blowfish
+insert into encdata (id, data) values (2, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQIOAywibh/+XMfUEAf+OINhBngEsw4a/IJIeJvUgv1gTQzBwOdQEuc/runr4Oa8
+Skw/Bj0X/zgABVZLem1a35NHaNwaQaCFwMQ41YyWCu+jTdsiyX/Nw0w8LKKz0rNC
+vVpG6YuV7Turtsf8a5lXy1K0SHkLlgxQ6c76GS4gtSl5+bsL2+5R1gSRJ9NXqCQP
+OHRipEiYwBPqr5R21ZG0FXXNKGOGkj6jt/M/wh3WVtAhYuBI+HPKRfAEjd/Pu/eD
+e1zYtkH1dKKFmp44+nF0tTI274xpuso7ShfKYrOK3saFWrl0DWiWteUinjSA1YBY
+m7dG7NZ8PW+g1SZWhEoPjEEEHz3kWMvlKheMRDudnQf/dDyX6kZVIAQF/5B012hq
+QyVewgTGysowFIDn01uIewoEA9cASw699jw9IoJp+k5WZXnU+INllBLzQxniQCSu
+iEcr0x3fYqNtj9QBfbIqyRcY6HTWcmzyOUeGaSyX76j+tRAvtVtXpraFFFnaHB70
+YpXTjLkp8EBafzMghFaKDeXlr2TG/T7rbwcwWrFIwPqEAUKWN5m97Q3eyo8/ioMd
+YoFD64J9ovSsgbuU5IpIGAsjxK+NKzg/2STH7zZFEVCtgcIXsTHTZfiwS98/+1H9
+p1DIDaXIcUFV2ztmcKxh9gt2sXRz1W+x6D8O0k3nanU5yGG4miLKaq18fbcA0BD1
++NIzAfelq6nvvxYKcGcamBMgLo5JkZOBHvyr6RsAKIT5QYc0QTjysTk9l0Am3gYc
+G2pAE+3k
+=TBHV
+-----END PGP MESSAGE-----
+');
+
+-- elg4096 / aes256
+insert into encdata (id, data) values (3, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQQOA7aFBP0Sjh/5EA/+JCgncc8IZmmRjPStWnGf9tVJhgHTn+smIclibGzs0deS
+SPSCitzpblwbUDvu964+/5e5Q1l7rRuNN+AgETlEd4eppv7Swn2ChdgOXxRwukcT
+Nh3G+PTFvD4ayi7w1db3qvXIt0MwN4Alt436wJmK1oz2Ka9IcyO+wHWrDy1nSGSx
+z5x7YEj+EZPgWc/YAvudqE8Jpzd/OT5zSHN09UFkIAk6NxisKaIstbEGFgpqtoDZ
+1SJM84XAdL2IcaJ3YY7k/yzwlawhsakKd4GSd5vWmAwvyzzbSiBMfKsDE16ePLNU
+ZBF7CzmlCBPZ7YrFAHLpXBXXkCQvzD2BEYOjse50ZEfJ036T7950Ozcdy1EQbGon
+nyQ4Gh0PBpnMcBuiXOceWuYzhlzFOzDtlVKdNTxFRDcbEyW2jo9xQYvCCLnYy8EH
+2M7S8jCtVYJBbn63a82ELv+3+kWYcsvBJv2ZVBh4ncrBu9o0P+OYS7ApoOU+j6p2
++t0RXHksqXS1YiUwYF5KSw09EbYMgNZ9G04Px/PxLU6fSC9iDrGX7Xt3kOUP0mku
+C518fPckT0zzRXqfFruJNRzDytW50KxkOQZzU1/Az1YlYN9QzWeU4EtLPb2fftZo
+D0qH/ln+f9Op5t6sD2fcxZVECU1b/bFtZsxvwH406YL+UQ7hU/XnZrzVVzODal8P
+/j1hg7v7BdJqu1DTp9nFWUuwMFcYAczuXn29IG183NZ7Ts4whDeYEhS8eNoLPX4j
+txY12ILD/w/3Q4LoW/hPa6OdfEzsn0U5GLf1WiGmJE1H6ft2U/xUnerc/u0kt+FU
+WAisArd4MuKtf7B5Vu/VF3kUdrR0hTniUKUivmC4o1jSId31Dufxj4aadVyldXAr
+6TNBcdyragZjxEZ6hsBCYzA0Rd1a8atd6OaQoIEEfAzCu5Ks29pydHErStYGjWJ1
+KA5KPLVvjbHpDmRhlCcm8vgpYQsBYEB5gE9fx5yCTlsVhCB6y23h7hfdMqerDqkO
+ZOPsO5h+tiHCdIrQ36sMjuINy1/K2rYcXd+Crh2iHcfidpU9fvDz2ihTRNQlhjuT
+0cQZM5JhctEx4VXF4LDctRhit7Hn0iqsk604woQfJVvP8O673xSXT/kBY0A/v9C0
+3C4YoFNeSaKwbfZQ/4u1ZFPJxK2IIJa8UGpyAUewLMlzGVVagljybv/f4Z9ERAhy
+huq5sMmw8UPsrJF2TUGHz5WSIwoh0J/qovoQI09I9sdEnFczDvRavMO2Mldy3E5i
+exz9oewtel6GOmsZQSYWT/vJzbYMmvHNmNpVwwoKrLV6oI3kyQ80GHBwI1WlwHoK
+2iRB0w8q4VVvJeYAz8ZIp380cqC3pfO0uZsrOx4g3k4X0jsB5y7rF5xXcZfnVbvG
+DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ==
+=L/M/
+-----END PGP MESSAGE-----
+');
+
+-- rsaenc2048 / aes128
+insert into encdata (id, data) values (4, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r
+pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg
+DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR
+yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb
+VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4
+HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK
+eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL
+GQ==
+=XHkF
+-----END PGP MESSAGE-----
+');
+
+-- successful decrypt
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=1 and encdata.id=1;
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=2 and encdata.id=2;
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=3 and encdata.id=3;
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=6 and encdata.id=4;
+
+-- wrong key
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=2 and encdata.id=1;
+
+-- sign-only key
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=4 and encdata.id=1;
+
+-- password-protected secret key, no password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+
+-- password-protected secret key, wrong password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'foo')
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+
+-- password-protected secret key, right password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool')
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql b/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
new file mode 100644
index 0000000..879b47f
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql
@@ -0,0 +1,50 @@
+--
+-- PGP Public Key Encryption
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+-- successful encrypt/decrypt
+select pgp_pub_decrypt(
+	pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+	dearmor(seckey))
+from keytbl where keytbl.id=1;
+
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=2;
+
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=3;
+
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=6;
+
+-- try with rsa-sign only
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=4;
+
+-- try with secret key
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(seckey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=1;
+
+-- does text-to-bytea works
+select pgp_pub_decrypt_bytea(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=1;
+
+-- and bytea-to-text?
+select pgp_pub_decrypt(
+		pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=1;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-zlib-DISABLED.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-zlib-DISABLED.sql b/contrib/pgcrypto/sql/pgp-zlib-DISABLED.sql
new file mode 100644
index 0000000..6f4eccd
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-zlib-DISABLED.sql
@@ -0,0 +1 @@
+-- zlib is disabled

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/rijndael.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/rijndael.sql b/contrib/pgcrypto/sql/rijndael.sql
new file mode 100644
index 0000000..bfbf95d
--- /dev/null
+++ b/contrib/pgcrypto/sql/rijndael.sql
@@ -0,0 +1,63 @@
+--
+-- AES / Rijndael-128 cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+-- some standard Rijndael testvalues
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f', 'hex'),
+'aes-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f1011121314151617', 'hex'),
+'aes-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'),
+'aes-ecb/pad:none'), 'hex');
+
+-- cbc
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'),
+'aes-cbc/pad:none'), 'hex');
+
+-- key padding
+
+SELECT encode(encrypt(
+decode('0011223344', 'hex'),
+decode('000102030405', 'hex'),
+'aes-cbc'), 'hex');
+
+SELECT encode(encrypt(
+decode('0011223344', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f10111213', 'hex'),
+'aes-cbc'), 'hex');
+
+SELECT encode(encrypt(
+decode('0011223344', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b', 'hex'),
+'aes-cbc'), 'hex');
+
+-- empty data
+select encode(encrypt('', 'foo', 'aes'), 'hex');
+-- 10 bytes key
+select encode(encrypt('foo', '0123456789', 'aes'), 'hex');
+-- 22 bytes key
+select encode(encrypt('foo', '0123456789012345678901', 'aes'), 'hex');
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'aes'), '0123456', 'aes');
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'aes'), 'hex');
+select decrypt_iv(decode('2c24cb7da91d6d5699801268b0f5adad', 'hex'),
+		'0123456', 'abcd', 'aes');
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'aes'), 'hex');
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'aes'), '0123456789', 'aes');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/sha1.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/sha1.sql b/contrib/pgcrypto/sql/sha1.sql
new file mode 100644
index 0000000..32b1f06
--- /dev/null
+++ b/contrib/pgcrypto/sql/sha1.sql
@@ -0,0 +1,11 @@
+--
+-- SHA1 message digest
+--
+
+SELECT encode(digest('', 'sha1'), 'hex');
+SELECT encode(digest('a', 'sha1'), 'hex');
+SELECT encode(digest('abc', 'sha1'), 'hex');
+SELECT encode(digest('message digest', 'sha1'), 'hex');
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyz', 'sha1'), 'hex');
+SELECT encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'sha1'), 'hex');
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha1'), 'hex');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/sha2.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/sha2.sql b/contrib/pgcrypto/sql/sha2.sql
new file mode 100644
index 0000000..3fe63d3
--- /dev/null
+++ b/contrib/pgcrypto/sql/sha2.sql
@@ -0,0 +1,33 @@
+--
+-- SHA2 family
+--
+
+-- SHA224
+SELECT encode(digest('', 'sha224'), 'hex');
+SELECT encode(digest('a', 'sha224'), 'hex');
+SELECT encode(digest('abc', 'sha224'), 'hex');
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha224'), 'hex');
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha224'), 'hex');
+
+-- SHA256
+SELECT encode(digest('', 'sha256'), 'hex');
+SELECT encode(digest('a', 'sha256'), 'hex');
+SELECT encode(digest('abc', 'sha256'), 'hex');
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha256'), 'hex');
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha256'), 'hex');
+
+-- SHA384
+SELECT encode(digest('', 'sha384'), 'hex');
+SELECT encode(digest('a', 'sha384'), 'hex');
+SELECT encode(digest('abc', 'sha384'), 'hex');
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha384'), 'hex');
+SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha384'), 'hex');
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha384'), 'hex');
+
+-- SHA512
+SELECT encode(digest('', 'sha512'), 'hex');
+SELECT encode(digest('a', 'sha512'), 'hex');
+SELECT encode(digest('abc', 'sha512'), 'hex');
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha512'), 'hex');
+SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha512'), 'hex');
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha512'), 'hex');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/uninstall_pgcrypto.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/uninstall_pgcrypto.sql b/contrib/pgcrypto/uninstall_pgcrypto.sql
new file mode 100644
index 0000000..a2891f6
--- /dev/null
+++ b/contrib/pgcrypto/uninstall_pgcrypto.sql
@@ -0,0 +1,46 @@
+/* $PostgreSQL: pgsql/contrib/pgcrypto/uninstall_pgcrypto.sql,v 1.4 2007/11/13 04:24:28 momjian Exp $ */
+
+-- Adjust this setting to control where the objects get dropped.
+SET search_path = public;
+
+DROP FUNCTION digest(text, text);
+DROP FUNCTION digest(bytea, text);
+
+DROP FUNCTION hmac(text, text, text);
+DROP FUNCTION hmac(bytea, bytea, text);
+
+DROP FUNCTION crypt(text, text);
+DROP FUNCTION gen_salt(text);
+DROP FUNCTION gen_salt(text, int4);
+
+DROP FUNCTION encrypt(bytea, bytea, text);
+DROP FUNCTION decrypt(bytea, bytea, text);
+DROP FUNCTION encrypt_iv(bytea, bytea, bytea, text);
+DROP FUNCTION decrypt_iv(bytea, bytea, bytea, text);
+
+DROP FUNCTION gen_random_bytes(int4);
+
+DROP FUNCTION pgp_sym_encrypt(text, text);
+DROP FUNCTION pgp_sym_encrypt_bytea(bytea, text);
+DROP FUNCTION pgp_sym_encrypt(text, text, text);
+DROP FUNCTION pgp_sym_encrypt_bytea(bytea, text, text);
+DROP FUNCTION pgp_sym_decrypt(bytea, text);
+DROP FUNCTION pgp_sym_decrypt_bytea(bytea, text);
+DROP FUNCTION pgp_sym_decrypt(bytea, text, text);
+DROP FUNCTION pgp_sym_decrypt_bytea(bytea, text, text);
+
+DROP FUNCTION pgp_pub_encrypt(text, bytea);
+DROP FUNCTION pgp_pub_encrypt_bytea(bytea, bytea);
+DROP FUNCTION pgp_pub_encrypt(text, bytea, text);
+DROP FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text);
+DROP FUNCTION pgp_pub_decrypt(bytea, bytea);
+DROP FUNCTION pgp_pub_decrypt_bytea(bytea, bytea);
+DROP FUNCTION pgp_pub_decrypt(bytea, bytea, text);
+DROP FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text);
+DROP FUNCTION pgp_pub_decrypt(bytea, bytea, text, text);
+DROP FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text);
+
+DROP FUNCTION pgp_key_id(bytea);
+DROP FUNCTION armor(bytea);
+DROP FUNCTION dearmor(text);
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/depends/thirdparty/.gitignore
----------------------------------------------------------------------
diff --git a/depends/thirdparty/.gitignore b/depends/thirdparty/.gitignore
index 0644298..2931c05 100644
--- a/depends/thirdparty/.gitignore
+++ b/depends/thirdparty/.gitignore
@@ -4,4 +4,3 @@
 gp-xerces/
 gporca/
 gpos/
-postgres/

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/depends/thirdparty/README
----------------------------------------------------------------------
diff --git a/depends/thirdparty/README b/depends/thirdparty/README
index 141a4ef..ff535a8 100644
--- a/depends/thirdparty/README
+++ b/depends/thirdparty/README
@@ -1,5 +1,4 @@
 Please do not create following directories yourselves:
-	gporca, gp-xerces, gpos, postgres
+	gporca, gp-xerces, gpos
 since they are auto-created and used when building some related features, i.e.
-orca support (enable-orca), pgcrypto support (with-pgcrypto).
-See src/backend/Makefile and contrib/Makefile for details.
+orca support (enable-orca). See src/backend/Makefile for details.

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/depends/thirdparty/postgres.commit
----------------------------------------------------------------------
diff --git a/depends/thirdparty/postgres.commit b/depends/thirdparty/postgres.commit
deleted file mode 100644
index fb7c7be..0000000
--- a/depends/thirdparty/postgres.commit
+++ /dev/null
@@ -1 +0,0 @@
-932ded2ed51e8333852e370c7a6dad75d9f236f9



[06/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto.sql.in
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgcrypto.sql.in b/contrib/pgcrypto/pgcrypto.sql.in
new file mode 100644
index 0000000..8388e86
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto.sql.in
@@ -0,0 +1,203 @@
+/* $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.sql.in,v 1.15 2007/11/13 04:24:28 momjian Exp $ */
+
+-- Adjust this setting to control where the objects get created.
+SET search_path = public;
+
+CREATE OR REPLACE FUNCTION digest(text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_digest'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION digest(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_digest'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION hmac(text, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_hmac'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION hmac(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_hmac'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION crypt(text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_crypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION gen_salt(text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_gen_salt'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE OR REPLACE FUNCTION gen_salt(text, int4)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_gen_salt_rounds'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE OR REPLACE FUNCTION encrypt(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_encrypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION decrypt(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_decrypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION encrypt_iv(bytea, bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_encrypt_iv'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION decrypt_iv(bytea, bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_decrypt_iv'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION gen_random_bytes(int4)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_random_bytes'
+LANGUAGE 'C' VOLATILE STRICT;
+
+--
+-- pgp_sym_encrypt(data, key)
+--
+CREATE OR REPLACE FUNCTION pgp_sym_encrypt(text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_sym_encrypt_bytea(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_sym_encrypt(data, key, args)
+--
+CREATE OR REPLACE FUNCTION pgp_sym_encrypt(text, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_sym_encrypt_bytea(bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_sym_decrypt(data, key)
+--
+CREATE OR REPLACE FUNCTION pgp_sym_decrypt(bytea, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_sym_decrypt_bytea(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_sym_decrypt(data, key, args)
+--
+CREATE OR REPLACE FUNCTION pgp_sym_decrypt(bytea, text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_sym_decrypt_bytea(bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_encrypt(data, key)
+--
+CREATE OR REPLACE FUNCTION pgp_pub_encrypt(text, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_pub_encrypt(data, key, args)
+--
+CREATE OR REPLACE FUNCTION pgp_pub_encrypt(text, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_pub_decrypt(data, key)
+--
+CREATE OR REPLACE FUNCTION pgp_pub_decrypt(bytea, bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_decrypt(data, key, psw)
+--
+CREATE OR REPLACE FUNCTION pgp_pub_decrypt(bytea, bytea, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_decrypt(data, key, psw, arg)
+--
+CREATE OR REPLACE FUNCTION pgp_pub_decrypt(bytea, bytea, text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- PGP key ID
+--
+CREATE OR REPLACE FUNCTION pgp_key_id(bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_key_id_w'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp armor
+--
+CREATE OR REPLACE FUNCTION armor(bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_armor'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OR REPLACE FUNCTION dearmor(text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_dearmor'
+LANGUAGE C IMMUTABLE STRICT;
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-armor.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-armor.c b/contrib/pgcrypto/pgp-armor.c
new file mode 100644
index 0000000..87adf91
--- /dev/null
+++ b/contrib/pgcrypto/pgp-armor.c
@@ -0,0 +1,383 @@
+/*
+ * pgp-armor.c
+ *		PGP ascii-armor.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-armor.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+/*
+ * BASE64 - duplicated :(
+ */
+
+static const unsigned char _base64[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int
+b64_encode(const uint8 *src, unsigned len, uint8 *dst)
+{
+	uint8	   *p,
+			   *lend = dst + 76;
+	const uint8 *s,
+			   *end = src + len;
+	int			pos = 2;
+	unsigned long buf = 0;
+
+	s = src;
+	p = dst;
+
+	while (s < end)
+	{
+		buf |= *s << (pos << 3);
+		pos--;
+		s++;
+
+		/*
+		 * write it out
+		 */
+		if (pos < 0)
+		{
+			*p++ = _base64[(buf >> 18) & 0x3f];
+			*p++ = _base64[(buf >> 12) & 0x3f];
+			*p++ = _base64[(buf >> 6) & 0x3f];
+			*p++ = _base64[buf & 0x3f];
+
+			pos = 2;
+			buf = 0;
+		}
+		if (p >= lend)
+		{
+			*p++ = '\n';
+			lend = p + 76;
+		}
+	}
+	if (pos != 2)
+	{
+		*p++ = _base64[(buf >> 18) & 0x3f];
+		*p++ = _base64[(buf >> 12) & 0x3f];
+		*p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '=';
+		*p++ = '=';
+	}
+
+	return p - dst;
+}
+
+/* probably should use lookup table */
+static int
+b64_decode(const uint8 *src, unsigned len, uint8 *dst)
+{
+	const uint8 *srcend = src + len,
+			   *s = src;
+	uint8	   *p = dst;
+	char		c;
+	unsigned	b = 0;
+	unsigned long buf = 0;
+	int			pos = 0,
+				end = 0;
+
+	while (s < srcend)
+	{
+		c = *s++;
+		if (c >= 'A' && c <= 'Z')
+			b = c - 'A';
+		else if (c >= 'a' && c <= 'z')
+			b = c - 'a' + 26;
+		else if (c >= '0' && c <= '9')
+			b = c - '0' + 52;
+		else if (c == '+')
+			b = 62;
+		else if (c == '/')
+			b = 63;
+		else if (c == '=')
+		{
+			/*
+			 * end sequence
+			 */
+			if (!end)
+			{
+				if (pos == 2)
+					end = 1;
+				else if (pos == 3)
+					end = 2;
+				else
+					return PXE_PGP_CORRUPT_ARMOR;
+			}
+			b = 0;
+		}
+		else if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
+			continue;
+		else
+			return PXE_PGP_CORRUPT_ARMOR;
+
+		/*
+		 * add it to buffer
+		 */
+		buf = (buf << 6) + b;
+		pos++;
+		if (pos == 4)
+		{
+			*p++ = (buf >> 16) & 255;
+			if (end == 0 || end > 1)
+				*p++ = (buf >> 8) & 255;
+			if (end == 0 || end > 2)
+				*p++ = buf & 255;
+			buf = 0;
+			pos = 0;
+		}
+	}
+
+	if (pos != 0)
+		return PXE_PGP_CORRUPT_ARMOR;
+	return p - dst;
+}
+
+static unsigned
+b64_enc_len(unsigned srclen)
+{
+	/*
+	 * 3 bytes will be converted to 4, linefeed after 76 chars
+	 */
+	return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4);
+}
+
+static unsigned
+b64_dec_len(unsigned srclen)
+{
+	return (srclen * 3) >> 2;
+}
+
+/*
+ * PGP armor
+ */
+
+static const char *armor_header = "-----BEGIN PGP MESSAGE-----\n\n";
+static const char *armor_footer = "\n-----END PGP MESSAGE-----\n";
+
+/* CRC24 implementation from rfc2440 */
+#define CRC24_INIT 0x00b704ceL
+#define CRC24_POLY 0x01864cfbL
+static long
+crc24(const uint8 *data, unsigned len)
+{
+	unsigned	crc = CRC24_INIT;
+	int			i;
+
+	while (len--)
+	{
+		crc ^= (*data++) << 16;
+		for (i = 0; i < 8; i++)
+		{
+			crc <<= 1;
+			if (crc & 0x1000000)
+				crc ^= CRC24_POLY;
+		}
+	}
+	return crc & 0xffffffL;
+}
+
+int
+pgp_armor_encode(const uint8 *src, unsigned len, uint8 *dst)
+{
+	int			n;
+	uint8	   *pos = dst;
+	unsigned	crc = crc24(src, len);
+
+	n = strlen(armor_header);
+	memcpy(pos, armor_header, n);
+	pos += n;
+
+	n = b64_encode(src, len, pos);
+	pos += n;
+
+	if (*(pos - 1) != '\n')
+		*pos++ = '\n';
+
+	*pos++ = '=';
+	pos[3] = _base64[crc & 0x3f];
+	crc >>= 6;
+	pos[2] = _base64[crc & 0x3f];
+	crc >>= 6;
+	pos[1] = _base64[crc & 0x3f];
+	crc >>= 6;
+	pos[0] = _base64[crc & 0x3f];
+	pos += 4;
+
+	n = strlen(armor_footer);
+	memcpy(pos, armor_footer, n);
+	pos += n;
+
+	return pos - dst;
+}
+
+static const uint8 *
+find_str(const uint8 *data, const uint8 *data_end, const char *str, int strlen)
+{
+	const uint8 *p = data;
+
+	if (!strlen)
+		return NULL;
+	if (data_end - data < strlen)
+		return NULL;
+	while (p < data_end)
+	{
+		p = memchr(p, str[0], data_end - p);
+		if (p == NULL)
+			return NULL;
+		if (p + strlen > data_end)
+			return NULL;
+		if (memcmp(p, str, strlen) == 0)
+			return p;
+		p++;
+	}
+	return NULL;
+}
+
+static int
+find_header(const uint8 *data, const uint8 *datend,
+			const uint8 **start_p, int is_end)
+{
+	const uint8 *p = data;
+	static const char *start_sep = "-----BEGIN";
+	static const char *end_sep = "-----END";
+	const char *sep = is_end ? end_sep : start_sep;
+
+	/* find header line */
+	while (1)
+	{
+		p = find_str(p, datend, sep, strlen(sep));
+		if (p == NULL)
+			return PXE_PGP_CORRUPT_ARMOR;
+		/* it must start at beginning of line */
+		if (p == data || *(p - 1) == '\n')
+			break;
+		p += strlen(sep);
+	}
+	*start_p = p;
+	p += strlen(sep);
+
+	/* check if header text ok */
+	for (; p < datend && *p != '-'; p++)
+	{
+		/* various junk can be there, but definitely not line-feed	*/
+		if (*p >= ' ')
+			continue;
+		return PXE_PGP_CORRUPT_ARMOR;
+	}
+	if (datend - p < 5 || memcmp(p, sep, 5) != 0)
+		return PXE_PGP_CORRUPT_ARMOR;
+	p += 5;
+
+	/* check if at end of line */
+	if (p < datend)
+	{
+		if (*p != '\n' && *p != '\r')
+			return PXE_PGP_CORRUPT_ARMOR;
+		if (*p == '\r')
+			p++;
+		if (p < datend && *p == '\n')
+			p++;
+	}
+	return p - *start_p;
+}
+
+int
+pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst)
+{
+	const uint8 *p = src;
+	const uint8 *data_end = src + len;
+	long		crc;
+	const uint8 *base64_start,
+			   *armor_end;
+	const uint8 *base64_end = NULL;
+	uint8		buf[4];
+	int			hlen;
+	int			res = PXE_PGP_CORRUPT_ARMOR;
+
+	/* armor start */
+	hlen = find_header(src, data_end, &p, 0);
+	if (hlen <= 0)
+		goto out;
+	p += hlen;
+
+	/* armor end */
+	hlen = find_header(p, data_end, &armor_end, 1);
+	if (hlen <= 0)
+		goto out;
+
+	/* skip comments - find empty line */
+	while (p < armor_end && *p != '\n' && *p != '\r')
+	{
+		p = memchr(p, '\n', armor_end - p);
+		if (!p)
+			goto out;
+
+		/* step to start of next line */
+		p++;
+	}
+	base64_start = p;
+
+	/* find crc pos */
+	for (p = armor_end; p >= base64_start; p--)
+		if (*p == '=')
+		{
+			base64_end = p - 1;
+			break;
+		}
+	if (base64_end == NULL)
+		goto out;
+
+	/* decode crc */
+	if (b64_decode(p + 1, 4, buf) != 3)
+		goto out;
+	crc = (((long) buf[0]) << 16) + (((long) buf[1]) << 8) + (long) buf[2];
+
+	/* decode data */
+	res = b64_decode(base64_start, base64_end - base64_start, dst);
+
+	/* check crc */
+	if (res >= 0 && crc24(dst, res) != crc)
+		res = PXE_PGP_CORRUPT_ARMOR;
+out:
+	return res;
+}
+
+unsigned
+pgp_armor_enc_len(unsigned len)
+{
+	return b64_enc_len(len) + strlen(armor_header) + strlen(armor_footer) + 16;
+}
+
+unsigned
+pgp_armor_dec_len(unsigned len)
+{
+	return b64_dec_len(len);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-cfb.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-cfb.c b/contrib/pgcrypto/pgp-cfb.c
new file mode 100644
index 0000000..7cf9bf0
--- /dev/null
+++ b/contrib/pgcrypto/pgp-cfb.c
@@ -0,0 +1,265 @@
+/*
+ * pgp-cfb.c
+ *	  Implements both normal and PGP-specific CFB mode.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-cfb.c
+ */
+
+#include "postgres.h"
+
+#include "mbuf.h"
+#include "px.h"
+#include "pgp.h"
+
+typedef int (*mix_data_t) (PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
+
+struct PGP_CFB
+{
+	PX_Cipher  *ciph;
+	int			block_size;
+	int			pos;
+	int			block_no;
+	int			resync;
+	uint8		fr[PGP_MAX_BLOCK];
+	uint8		fre[PGP_MAX_BLOCK];
+	uint8		encbuf[PGP_MAX_BLOCK];
+};
+
+int
+pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len,
+			   int resync, uint8 *iv)
+{
+	int			res;
+	PX_Cipher  *ciph;
+	PGP_CFB    *ctx;
+
+	res = pgp_load_cipher(algo, &ciph);
+	if (res < 0)
+		return res;
+
+	res = px_cipher_init(ciph, key, key_len, NULL);
+	if (res < 0)
+	{
+		px_cipher_free(ciph);
+		return res;
+	}
+
+	ctx = px_alloc(sizeof(*ctx));
+	memset(ctx, 0, sizeof(*ctx));
+	ctx->ciph = ciph;
+	ctx->block_size = px_cipher_block_size(ciph);
+	ctx->resync = resync;
+
+	if (iv)
+		memcpy(ctx->fr, iv, ctx->block_size);
+
+	*ctx_p = ctx;
+	return 0;
+}
+
+void
+pgp_cfb_free(PGP_CFB *ctx)
+{
+	px_cipher_free(ctx->ciph);
+	memset(ctx, 0, sizeof(*ctx));
+	px_free(ctx);
+}
+
+/*
+ * Data processing for normal CFB.	(PGP_PKT_SYMENCRYPTED_DATA_MDC)
+ */
+static int
+mix_encrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
+{
+	int			i;
+
+	for (i = ctx->pos; i < ctx->pos + len; i++)
+		*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
+	ctx->pos += len;
+	return len;
+}
+
+static int
+mix_decrypt_normal(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
+{
+	int			i;
+
+	for (i = ctx->pos; i < ctx->pos + len; i++)
+	{
+		ctx->encbuf[i] = *data++;
+		*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
+	}
+	ctx->pos += len;
+	return len;
+}
+
+/*
+ * Data processing for old PGP CFB mode. (PGP_PKT_SYMENCRYPTED_DATA)
+ *
+ * The goal is to hide the horror from the rest of the code,
+ * thus its all concentrated here.
+ */
+static int
+mix_encrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
+{
+	int			i,
+				n;
+
+	/* block #2 is 2 bytes long */
+	if (ctx->block_no == 2)
+	{
+		n = 2 - ctx->pos;
+		if (len < n)
+			n = len;
+		for (i = ctx->pos; i < ctx->pos + n; i++)
+			*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
+
+		ctx->pos += n;
+		len -= n;
+
+		if (ctx->pos == 2)
+		{
+			memcpy(ctx->fr, ctx->encbuf + 2, ctx->block_size - 2);
+			memcpy(ctx->fr + ctx->block_size - 2, ctx->encbuf, 2);
+			ctx->pos = 0;
+			return n;
+		}
+	}
+	for (i = ctx->pos; i < ctx->pos + len; i++)
+		*dst++ = ctx->encbuf[i] = ctx->fre[i] ^ (*data++);
+	ctx->pos += len;
+	return len;
+}
+
+static int
+mix_decrypt_resync(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
+{
+	int			i,
+				n;
+
+	/* block #2 is 2 bytes long */
+	if (ctx->block_no == 2)
+	{
+		n = 2 - ctx->pos;
+		if (len < n)
+			n = len;
+		for (i = ctx->pos; i < ctx->pos + n; i++)
+		{
+			ctx->encbuf[i] = *data++;
+			*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
+		}
+		ctx->pos += n;
+		len -= n;
+
+		if (ctx->pos == 2)
+		{
+			memcpy(ctx->fr, ctx->encbuf + 2, ctx->block_size - 2);
+			memcpy(ctx->fr + ctx->block_size - 2, ctx->encbuf, 2);
+			ctx->pos = 0;
+			return n;
+		}
+	}
+	for (i = ctx->pos; i < ctx->pos + len; i++)
+	{
+		ctx->encbuf[i] = *data++;
+		*dst++ = ctx->fre[i] ^ ctx->encbuf[i];
+	}
+	ctx->pos += len;
+	return len;
+}
+
+/*
+ * common code for both encrypt and decrypt.
+ */
+static int
+cfb_process(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst,
+			mix_data_t mix_data)
+{
+	int			n;
+	int			res;
+
+	while (len > 0 && ctx->pos > 0)
+	{
+		n = ctx->block_size - ctx->pos;
+		if (len < n)
+			n = len;
+
+		n = mix_data(ctx, data, n, dst);
+		data += n;
+		dst += n;
+		len -= n;
+
+		if (ctx->pos == ctx->block_size)
+		{
+			memcpy(ctx->fr, ctx->encbuf, ctx->block_size);
+			ctx->pos = 0;
+		}
+	}
+
+	while (len > 0)
+	{
+		px_cipher_encrypt(ctx->ciph, ctx->fr, ctx->block_size, ctx->fre);
+		if (ctx->block_no < 5)
+			ctx->block_no++;
+
+		n = ctx->block_size;
+		if (len < n)
+			n = len;
+
+		res = mix_data(ctx, data, n, dst);
+		data += res;
+		dst += res;
+		len -= res;
+
+		if (ctx->pos == ctx->block_size)
+		{
+			memcpy(ctx->fr, ctx->encbuf, ctx->block_size);
+			ctx->pos = 0;
+		}
+	}
+	return 0;
+}
+
+/*
+ * public interface
+ */
+
+int
+pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
+{
+	mix_data_t	mix = ctx->resync ? mix_encrypt_resync : mix_encrypt_normal;
+
+	return cfb_process(ctx, data, len, dst, mix);
+}
+
+int
+pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst)
+{
+	mix_data_t	mix = ctx->resync ? mix_decrypt_resync : mix_decrypt_normal;
+
+	return cfb_process(ctx, data, len, dst, mix);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-compress.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-compress.c b/contrib/pgcrypto/pgp-compress.c
new file mode 100644
index 0000000..c592453
--- /dev/null
+++ b/contrib/pgcrypto/pgp-compress.c
@@ -0,0 +1,329 @@
+/*
+ * pgp-compress.c
+ *	  ZIP and ZLIB compression via zlib.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-compress.c
+ */
+
+#include "postgres.h"
+
+#include "mbuf.h"
+#include "px.h"
+#include "pgp.h"
+
+
+/*
+ * Compressed pkt writer
+ */
+
+#ifdef HAVE_LIBZ
+
+#include <zlib.h>
+
+#define ZIP_OUT_BUF 8192
+#define ZIP_IN_BLOCK 8192
+
+struct ZipStat
+{
+	uint8		type;
+	int			buf_len;
+	int			hdr_done;
+	z_stream	stream;
+	uint8		buf[ZIP_OUT_BUF];
+};
+
+static void *
+z_alloc(void *priv, unsigned n_items, unsigned item_len)
+{
+	return px_alloc(n_items * item_len);
+}
+
+static void
+z_free(void *priv, void *addr)
+{
+	px_free(addr);
+}
+
+static int
+compress_init(PushFilter *next, void *init_arg, void **priv_p)
+{
+	int			res;
+	struct ZipStat *st;
+	PGP_Context *ctx = init_arg;
+	uint8		type = ctx->compress_algo;
+
+	if (type != PGP_COMPR_ZLIB && type != PGP_COMPR_ZIP)
+		return PXE_PGP_UNSUPPORTED_COMPR;
+
+	/*
+	 * init
+	 */
+	st = px_alloc(sizeof(*st));
+	memset(st, 0, sizeof(*st));
+	st->buf_len = ZIP_OUT_BUF;
+	st->stream.zalloc = z_alloc;
+	st->stream.zfree = z_free;
+
+	if (type == PGP_COMPR_ZIP)
+		res = deflateInit2(&st->stream, ctx->compress_level,
+						   Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
+	else
+		res = deflateInit(&st->stream, ctx->compress_level);
+	if (res != Z_OK)
+	{
+		px_free(st);
+		return PXE_PGP_COMPRESSION_ERROR;
+	}
+	*priv_p = st;
+
+	return ZIP_IN_BLOCK;
+}
+
+/* writes compressed data packet */
+
+/* can handle zero-len incoming data, but shouldn't */
+static int
+compress_process(PushFilter *next, void *priv, const uint8 *data, int len)
+{
+	int			res,
+				n_out;
+	struct ZipStat *st = priv;
+
+	/*
+	 * process data
+	 */
+	while (len > 0)
+	{
+		st->stream.next_in = (void *) data;
+		st->stream.avail_in = len;
+		st->stream.next_out = st->buf;
+		st->stream.avail_out = st->buf_len;
+		res = deflate(&st->stream, 0);
+		if (res != Z_OK)
+			return PXE_PGP_COMPRESSION_ERROR;
+
+		n_out = st->buf_len - st->stream.avail_out;
+		if (n_out > 0)
+		{
+			res = pushf_write(next, st->buf, n_out);
+			if (res < 0)
+				return res;
+		}
+		len = st->stream.avail_in;
+	}
+
+	return 0;
+}
+
+static int
+compress_flush(PushFilter *next, void *priv)
+{
+	int			res,
+				zres,
+				n_out;
+	struct ZipStat *st = priv;
+
+	st->stream.next_in = NULL;
+	st->stream.avail_in = 0;
+	while (1)
+	{
+		st->stream.next_out = st->buf;
+		st->stream.avail_out = st->buf_len;
+		zres = deflate(&st->stream, Z_FINISH);
+		if (zres != Z_STREAM_END && zres != Z_OK)
+			return PXE_PGP_COMPRESSION_ERROR;
+		n_out = st->buf_len - st->stream.avail_out;
+		if (n_out > 0)
+		{
+			res = pushf_write(next, st->buf, n_out);
+			if (res < 0)
+				return res;
+		}
+		if (zres == Z_STREAM_END)
+			break;
+	}
+	return 0;
+}
+
+static void
+compress_free(void *priv)
+{
+	struct ZipStat *st = priv;
+
+	deflateEnd(&st->stream);
+	memset(st, 0, sizeof(*st));
+	px_free(st);
+}
+
+static const PushFilterOps
+			compress_filter = {
+	compress_init, compress_process, compress_flush, compress_free
+};
+
+int
+pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
+{
+	return pushf_create(res, &compress_filter, ctx, dst);
+}
+
+/*
+ * Decompress
+ */
+struct DecomprData
+{
+	int			buf_len;		/* = ZIP_OUT_BUF */
+	int			buf_data;		/* available data */
+	uint8	   *pos;
+	z_stream	stream;
+	int			eof;
+	uint8		buf[ZIP_OUT_BUF];
+};
+
+static int
+decompress_init(void **priv_p, void *arg, PullFilter *src)
+{
+	PGP_Context *ctx = arg;
+	struct DecomprData *dec;
+	int			res;
+
+	if (ctx->compress_algo != PGP_COMPR_ZLIB
+		&& ctx->compress_algo != PGP_COMPR_ZIP)
+		return PXE_PGP_UNSUPPORTED_COMPR;
+
+	dec = px_alloc(sizeof(*dec));
+	memset(dec, 0, sizeof(*dec));
+	dec->buf_len = ZIP_OUT_BUF;
+	*priv_p = dec;
+
+	dec->stream.zalloc = z_alloc;
+	dec->stream.zfree = z_free;
+
+	if (ctx->compress_algo == PGP_COMPR_ZIP)
+		res = inflateInit2(&dec->stream, -15);
+	else
+		res = inflateInit(&dec->stream);
+	if (res != Z_OK)
+	{
+		px_free(dec);
+		px_debug("decompress_init: inflateInit error");
+		return PXE_PGP_COMPRESSION_ERROR;
+	}
+
+	return 0;
+}
+
+static int
+decompress_read(void *priv, PullFilter *src, int len,
+				uint8 **data_p, uint8 *buf, int buflen)
+{
+	int			res;
+	int			flush;
+	struct DecomprData *dec = priv;
+
+restart:
+	if (dec->buf_data > 0)
+	{
+		if (len > dec->buf_data)
+			len = dec->buf_data;
+		*data_p = dec->pos;
+		dec->pos += len;
+		dec->buf_data -= len;
+		return len;
+	}
+
+	if (dec->eof)
+		return 0;
+
+	if (dec->stream.avail_in == 0)
+	{
+		uint8	   *tmp;
+
+		res = pullf_read(src, 8192, &tmp);
+		if (res < 0)
+			return res;
+		dec->stream.next_in = tmp;
+		dec->stream.avail_in = res;
+	}
+
+	dec->stream.next_out = dec->buf;
+	dec->stream.avail_out = dec->buf_len;
+	dec->pos = dec->buf;
+
+	/*
+	 * Z_SYNC_FLUSH is tell zlib to output as much as possible. It should do
+	 * it anyway (Z_NO_FLUSH), but seems to reserve the right not to.  So lets
+	 * follow the API.
+	 */
+	flush = dec->stream.avail_in ? Z_SYNC_FLUSH : Z_FINISH;
+	res = inflate(&dec->stream, flush);
+	if (res != Z_OK && res != Z_STREAM_END)
+	{
+		px_debug("decompress_read: inflate error: %d", res);
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	dec->buf_data = dec->buf_len - dec->stream.avail_out;
+	if (res == Z_STREAM_END)
+		dec->eof = 1;
+	goto restart;
+}
+
+static void
+decompress_free(void *priv)
+{
+	struct DecomprData *dec = priv;
+
+	inflateEnd(&dec->stream);
+	memset(dec, 0, sizeof(*dec));
+	px_free(dec);
+}
+
+static const PullFilterOps
+			decompress_filter = {
+	decompress_init, decompress_read, decompress_free
+};
+
+int
+pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
+{
+	return pullf_create(res, &decompress_filter, ctx, src);
+}
+#else							/* !HAVE_ZLIB */
+
+int
+pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
+{
+	return PXE_PGP_UNSUPPORTED_COMPR;
+}
+
+int
+pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
+{
+	return PXE_PGP_UNSUPPORTED_COMPR;
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-decrypt.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-decrypt.c b/contrib/pgcrypto/pgp-decrypt.c
new file mode 100644
index 0000000..c9aa6cd
--- /dev/null
+++ b/contrib/pgcrypto/pgp-decrypt.c
@@ -0,0 +1,1188 @@
+/*
+ * pgp-decrypt.c
+ *	  OpenPGP decrypt.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-decrypt.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+#define NO_CTX_SIZE		0
+#define ALLOW_CTX_SIZE	1
+#define NO_COMPR		0
+#define ALLOW_COMPR		1
+#define NO_MDC			0
+#define NEED_MDC		1
+
+#define PKT_NORMAL 1
+#define PKT_STREAM 2
+#define PKT_CONTEXT 3
+
+#define MAX_CHUNK (16*1024*1024)
+
+static int
+parse_new_len(PullFilter *src, int *len_p)
+{
+	uint8		b;
+	int			len;
+	int			pkttype = PKT_NORMAL;
+
+	GETBYTE(src, b);
+	if (b <= 191)
+		len = b;
+	else if (b >= 192 && b <= 223)
+	{
+		len = ((unsigned) (b) - 192) << 8;
+		GETBYTE(src, b);
+		len += 192 + b;
+	}
+	else if (b == 255)
+	{
+		GETBYTE(src, b);
+		len = b;
+		GETBYTE(src, b);
+		len = (len << 8) | b;
+		GETBYTE(src, b);
+		len = (len << 8) | b;
+		GETBYTE(src, b);
+		len = (len << 8) | b;
+	}
+	else
+	{
+		len = 1 << (b & 0x1F);
+		pkttype = PKT_STREAM;
+	}
+
+	if (len < 0 || len > MAX_CHUNK)
+	{
+		px_debug("parse_new_len: weird length");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	*len_p = len;
+	return pkttype;
+}
+
+static int
+parse_old_len(PullFilter *src, int *len_p, int lentype)
+{
+	uint8		b;
+	int			len;
+
+	GETBYTE(src, b);
+	len = b;
+
+	if (lentype == 1)
+	{
+		GETBYTE(src, b);
+		len = (len << 8) | b;
+	}
+	else if (lentype == 2)
+	{
+		GETBYTE(src, b);
+		len = (len << 8) | b;
+		GETBYTE(src, b);
+		len = (len << 8) | b;
+		GETBYTE(src, b);
+		len = (len << 8) | b;
+	}
+
+	if (len < 0 || len > MAX_CHUNK)
+	{
+		px_debug("parse_old_len: weird length");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	*len_p = len;
+	return PKT_NORMAL;
+}
+
+/* returns pkttype or 0 on eof */
+int
+pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
+{
+	int			lentype;
+	int			res;
+	uint8	   *p;
+
+	/* EOF is normal here, thus we dont use GETBYTE */
+	res = pullf_read(src, 1, &p);
+	if (res < 0)
+		return res;
+	if (res == 0)
+		return 0;
+
+	if ((*p & 0x80) == 0)
+	{
+		px_debug("pgp_parse_pkt_hdr: not pkt hdr");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	if (*p & 0x40)
+	{
+		*tag = *p & 0x3f;
+		res = parse_new_len(src, len_p);
+	}
+	else
+	{
+		lentype = *p & 3;
+		*tag = (*p >> 2) & 0x0F;
+		if (lentype == 3)
+			res = allow_ctx ? PKT_CONTEXT : PXE_PGP_CORRUPT_DATA;
+		else
+			res = parse_old_len(src, len_p, lentype);
+	}
+	return res;
+}
+
+/*
+ * Packet reader
+ */
+struct PktData
+{
+	int			type;
+	int			len;
+};
+
+static int
+pktreader_pull(void *priv, PullFilter *src, int len,
+			   uint8 **data_p, uint8 *buf, int buflen)
+{
+	int			res;
+	struct PktData *pkt = priv;
+
+	/* PKT_CONTEXT means: whatever there is */
+	if (pkt->type == PKT_CONTEXT)
+		return pullf_read(src, len, data_p);
+
+	if (pkt->len == 0)
+	{
+		/* this was last chunk in stream */
+		if (pkt->type == PKT_NORMAL)
+			return 0;
+
+		/* next chunk in stream */
+		res = parse_new_len(src, &pkt->len);
+		if (res < 0)
+			return res;
+		pkt->type = res;
+	}
+
+	if (len > pkt->len)
+		len = pkt->len;
+
+	res = pullf_read(src, len, data_p);
+	if (res > 0)
+		pkt->len -= res;
+
+	return res;
+}
+
+static void
+pktreader_free(void *priv)
+{
+	struct PktData *pkt = priv;
+
+	memset(pkt, 0, sizeof(*pkt));
+	px_free(pkt);
+}
+
+static struct PullFilterOps pktreader_filter = {
+	NULL, pktreader_pull, pktreader_free
+};
+
+/* needs helper function to pass several parameters */
+int
+pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
+					  int pkttype, PGP_Context *ctx)
+{
+	int			res;
+	struct PktData *pkt = px_alloc(sizeof(*pkt));
+
+	pkt->type = pkttype;
+	pkt->len = len;
+	res = pullf_create(pf_p, &pktreader_filter, pkt, src);
+	if (res < 0)
+		px_free(pkt);
+	return res;
+}
+
+/*
+ * Prefix check filter
+ */
+
+static int
+prefix_init(void **priv_p, void *arg, PullFilter *src)
+{
+	PGP_Context *ctx = arg;
+	int			len;
+	int			res;
+	uint8	   *buf;
+	uint8		tmpbuf[PGP_MAX_BLOCK + 2];
+
+	len = pgp_get_cipher_block_size(ctx->cipher_algo);
+	if (len > sizeof(tmpbuf))
+		return PXE_BUG;
+
+	res = pullf_read_max(src, len + 2, &buf, tmpbuf);
+	if (res < 0)
+		return res;
+	if (res != len + 2)
+	{
+		px_debug("prefix_init: short read");
+		memset(tmpbuf, 0, sizeof(tmpbuf));
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
+	{
+		px_debug("prefix_init: corrupt prefix");
+
+		/*
+		 * The original purpose of the 2-byte check was to show user a
+		 * friendly "wrong key" message. This made following possible:
+		 *
+		 * "An Attack on CFB Mode Encryption As Used By OpenPGP" by Serge
+		 * Mister and Robert Zuccherato
+		 *
+		 * To avoid being 'oracle', we delay reporting, which basically means
+		 * we prefer to run into corrupt packet header.
+		 *
+		 * We _could_ throw PXE_PGP_CORRUPT_DATA here, but there is
+		 * possibility of attack via timing, so we don't.
+		 */
+		ctx->corrupt_prefix = 1;
+	}
+	memset(tmpbuf, 0, sizeof(tmpbuf));
+	return 0;
+}
+
+static struct PullFilterOps prefix_filter = {
+	prefix_init, NULL, NULL
+};
+
+
+/*
+ * Decrypt filter
+ */
+
+static int
+decrypt_init(void **priv_p, void *arg, PullFilter *src)
+{
+	PGP_CFB    *cfb = arg;
+
+	*priv_p = cfb;
+
+	/* we need to write somewhere, so ask for a buffer */
+	return 4096;
+}
+
+static int
+decrypt_read(void *priv, PullFilter *src, int len,
+			 uint8 **data_p, uint8 *buf, int buflen)
+{
+	PGP_CFB    *cfb = priv;
+	uint8	   *tmp;
+	int			res;
+
+	res = pullf_read(src, len, &tmp);
+	if (res > 0)
+	{
+		pgp_cfb_decrypt(cfb, tmp, res, buf);
+		*data_p = buf;
+	}
+	return res;
+}
+
+struct PullFilterOps pgp_decrypt_filter = {
+	decrypt_init, decrypt_read, NULL
+};
+
+
+/*
+ * MDC hasher filter
+ */
+
+static int
+mdc_init(void **priv_p, void *arg, PullFilter *src)
+{
+	PGP_Context *ctx = arg;
+
+	*priv_p = ctx;
+	return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
+}
+
+static void
+mdc_free(void *priv)
+{
+	PGP_Context *ctx = priv;
+
+	if (ctx->use_mdcbuf_filter)
+		return;
+	px_md_free(ctx->mdc_ctx);
+	ctx->mdc_ctx = NULL;
+}
+
+static int
+mdc_finish(PGP_Context *ctx, PullFilter *src,
+		   int len, uint8 **data_p)
+{
+	int			res;
+	uint8		hash[20];
+	uint8		tmpbuf[22];
+
+	if (len + 1 > sizeof(tmpbuf))
+		return PXE_BUG;
+
+	/* read data */
+	res = pullf_read_max(src, len + 1, data_p, tmpbuf);
+	if (res < 0)
+		return res;
+	if (res == 0)
+	{
+		if (ctx->mdc_checked == 0)
+		{
+			px_debug("no mdc");
+			return PXE_PGP_CORRUPT_DATA;
+		}
+		return 0;
+	}
+
+	/* safety check */
+	if (ctx->in_mdc_pkt > 1)
+	{
+		px_debug("mdc_finish: several times here?");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	ctx->in_mdc_pkt++;
+
+	/* is the packet sane? */
+	if (res != 20)
+	{
+		px_debug("mdc_finish: read failed, res=%d", res);
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	/*
+	 * ok, we got the hash, now check
+	 */
+	px_md_finish(ctx->mdc_ctx, hash);
+	res = memcmp(hash, *data_p, 20);
+	memset(hash, 0, 20);
+	memset(tmpbuf, 0, sizeof(tmpbuf));
+	if (res != 0)
+	{
+		px_debug("mdc_finish: mdc failed");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	ctx->mdc_checked = 1;
+	return len;
+}
+
+static int
+mdc_read(void *priv, PullFilter *src, int len,
+		 uint8 **data_p, uint8 *buf, int buflen)
+{
+	int			res;
+	PGP_Context *ctx = priv;
+
+	/* skip this filter? */
+	if (ctx->use_mdcbuf_filter)
+		return pullf_read(src, len, data_p);
+
+	if (ctx->in_mdc_pkt)
+		return mdc_finish(ctx, src, len, data_p);
+
+	res = pullf_read(src, len, data_p);
+	if (res < 0)
+		return res;
+	if (res == 0)
+	{
+		px_debug("mdc_read: unexpected eof");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	px_md_update(ctx->mdc_ctx, *data_p, res);
+
+	return res;
+}
+
+static struct PullFilterOps mdc_filter = {
+	mdc_init, mdc_read, mdc_free
+};
+
+
+/*
+ * Combined Pkt reader and MDC hasher.
+ *
+ * For the case of SYMENCRYPTED_MDC packet, where
+ * the data part has 'context length', which means
+ * that data packet ends 22 bytes before end of parent
+ * packet, which is silly.
+ */
+#define MDCBUF_LEN 8192
+struct MDCBufData
+{
+	PGP_Context *ctx;
+	int			eof;
+	int			buflen;
+	int			avail;
+	uint8	   *pos;
+	int			mdc_avail;
+	uint8		mdc_buf[22];
+	uint8		buf[MDCBUF_LEN];
+};
+
+static int
+mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
+{
+	PGP_Context *ctx = arg;
+	struct MDCBufData *st;
+
+	st = px_alloc(sizeof(*st));
+	memset(st, 0, sizeof(*st));
+	st->buflen = sizeof(st->buf);
+	st->ctx = ctx;
+	*priv_p = st;
+
+	/* take over the work of mdc_filter */
+	ctx->use_mdcbuf_filter = 1;
+
+	return 0;
+}
+
+static int
+mdcbuf_finish(struct MDCBufData * st)
+{
+	uint8		hash[20];
+	int			res;
+
+	st->eof = 1;
+
+	if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
+	{
+		px_debug("mdcbuf_finish: bad MDC pkt hdr");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
+	px_md_finish(st->ctx->mdc_ctx, hash);
+	res = memcmp(hash, st->mdc_buf + 2, 20);
+	memset(hash, 0, 20);
+	if (res)
+	{
+		px_debug("mdcbuf_finish: MDC does not match");
+		res = PXE_PGP_CORRUPT_DATA;
+	}
+	return res;
+}
+
+static void
+mdcbuf_load_data(struct MDCBufData * st, uint8 *src, int len)
+{
+	uint8	   *dst = st->pos + st->avail;
+
+	memcpy(dst, src, len);
+	px_md_update(st->ctx->mdc_ctx, src, len);
+	st->avail += len;
+}
+
+static void
+mdcbuf_load_mdc(struct MDCBufData * st, uint8 *src, int len)
+{
+	memmove(st->mdc_buf + st->mdc_avail, src, len);
+	st->mdc_avail += len;
+}
+
+static int
+mdcbuf_refill(struct MDCBufData * st, PullFilter *src)
+{
+	uint8	   *data;
+	int			res;
+	int			need;
+
+	/* put avail data in start */
+	if (st->avail > 0 && st->pos != st->buf)
+		memmove(st->buf, st->pos, st->avail);
+	st->pos = st->buf;
+
+	/* read new data */
+	need = st->buflen + 22 - st->avail - st->mdc_avail;
+	res = pullf_read(src, need, &data);
+	if (res < 0)
+		return res;
+	if (res == 0)
+		return mdcbuf_finish(st);
+
+	/* add to buffer */
+	if (res >= 22)
+	{
+		mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
+		st->mdc_avail = 0;
+
+		mdcbuf_load_data(st, data, res - 22);
+		mdcbuf_load_mdc(st, data + res - 22, 22);
+	}
+	else
+	{
+		int			canmove = st->mdc_avail + res - 22;
+
+		if (canmove > 0)
+		{
+			mdcbuf_load_data(st, st->mdc_buf, canmove);
+			st->mdc_avail -= canmove;
+			memmove(st->mdc_buf, st->mdc_buf + canmove, st->mdc_avail);
+		}
+		mdcbuf_load_mdc(st, data, res);
+	}
+	return 0;
+}
+
+static int
+mdcbuf_read(void *priv, PullFilter *src, int len,
+			uint8 **data_p, uint8 *buf, int buflen)
+{
+	struct MDCBufData *st = priv;
+	int			res;
+
+	if (!st->eof && len > st->avail)
+	{
+		res = mdcbuf_refill(st, src);
+		if (res < 0)
+			return res;
+	}
+
+	if (len > st->avail)
+		len = st->avail;
+
+	*data_p = st->pos;
+	st->pos += len;
+	st->avail -= len;
+	return len;
+}
+
+static void
+mdcbuf_free(void *priv)
+{
+	struct MDCBufData *st = priv;
+
+	px_md_free(st->ctx->mdc_ctx);
+	st->ctx->mdc_ctx = NULL;
+	memset(st, 0, sizeof(*st));
+	px_free(st);
+}
+
+static struct PullFilterOps mdcbuf_filter = {
+	mdcbuf_init, mdcbuf_read, mdcbuf_free
+};
+
+
+/*
+ * Decrypt separate session key
+ */
+static int
+decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
+{
+	int			res;
+	uint8		algo;
+	PGP_CFB    *cfb;
+
+	res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
+						 ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
+	if (res < 0)
+		return res;
+
+	pgp_cfb_decrypt(cfb, src, 1, &algo);
+	src++;
+	len--;
+
+	pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
+	pgp_cfb_free(cfb);
+	ctx->sess_key_len = len;
+	ctx->cipher_algo = algo;
+
+	if (pgp_get_cipher_key_size(algo) != len)
+	{
+		px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
+				 algo, pgp_get_cipher_key_size(algo), len);
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	return 0;
+}
+
+/*
+ * Handle key packet
+ */
+static int
+parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
+{
+	uint8	   *p;
+	int			res;
+	uint8		tmpbuf[PGP_MAX_KEY + 2];
+	uint8		ver;
+
+	GETBYTE(src, ver);
+	GETBYTE(src, ctx->s2k_cipher_algo);
+	if (ver != 4)
+	{
+		px_debug("bad key pkt ver");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	/*
+	 * read S2K info
+	 */
+	res = pgp_s2k_read(src, &ctx->s2k);
+	if (res < 0)
+		return res;
+	ctx->s2k_mode = ctx->s2k.mode;
+	ctx->s2k_digest_algo = ctx->s2k.digest_algo;
+
+	/*
+	 * generate key from password
+	 */
+	res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
+						  ctx->sym_key, ctx->sym_key_len);
+	if (res < 0)
+		return res;
+
+	/*
+	 * do we have separate session key?
+	 */
+	res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
+	if (res < 0)
+		return res;
+
+	if (res == 0)
+	{
+		/*
+		 * no, s2k key is session key
+		 */
+		memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
+		ctx->sess_key_len = ctx->s2k.key_len;
+		ctx->cipher_algo = ctx->s2k_cipher_algo;
+		res = 0;
+		ctx->use_sess_key = 0;
+	}
+	else
+	{
+		/*
+		 * yes, decrypt it
+		 */
+		if (res < 17 || res > PGP_MAX_KEY + 1)
+		{
+			px_debug("expect key, but bad data");
+			return PXE_PGP_CORRUPT_DATA;
+		}
+		ctx->use_sess_key = 1;
+		res = decrypt_key(ctx, p, res);
+	}
+
+	memset(tmpbuf, 0, sizeof(tmpbuf));
+	return res;
+}
+
+static int
+copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
+{
+	uint8	   *data_end = data + len;
+	uint8		tmpbuf[1024];
+	uint8	   *tmp_end = tmpbuf + sizeof(tmpbuf);
+	uint8	   *p;
+	int			res;
+
+	p = tmpbuf;
+	if (*got_cr)
+	{
+		if (*data != '\n')
+			*p++ = '\r';
+		*got_cr = 0;
+	}
+	while (data < data_end)
+	{
+		if (*data == '\r')
+		{
+			if (data + 1 < data_end)
+			{
+				if (*(data + 1) == '\n')
+					data++;
+			}
+			else
+			{
+				*got_cr = 1;
+				break;
+			}
+		}
+		*p++ = *data++;
+		if (p >= tmp_end)
+		{
+			res = mbuf_append(dst, tmpbuf, p - tmpbuf);
+			if (res < 0)
+				return res;
+			p = tmpbuf;
+		}
+	}
+	if (p - tmpbuf > 0)
+	{
+		res = mbuf_append(dst, tmpbuf, p - tmpbuf);
+		if (res < 0)
+			return res;
+	}
+	return 0;
+}
+
+static int
+parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
+{
+	int			type;
+	int			name_len;
+	int			res;
+	uint8	   *buf;
+	uint8		tmpbuf[4];
+	int			got_cr = 0;
+
+	GETBYTE(pkt, type);
+	GETBYTE(pkt, name_len);
+
+	/* skip name */
+	while (name_len > 0)
+	{
+		res = pullf_read(pkt, name_len, &buf);
+		if (res < 0)
+			return res;
+		if (res == 0)
+			break;
+		name_len -= res;
+	}
+	if (name_len > 0)
+	{
+		px_debug("parse_literal_data: unexpected eof");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	/* skip date */
+	res = pullf_read_max(pkt, 4, &buf, tmpbuf);
+	if (res != 4)
+	{
+		px_debug("parse_literal_data: unexpected eof");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	memset(tmpbuf, 0, 4);
+
+	/* check if text */
+	if (ctx->text_mode)
+		if (type != 't' && type != 'u')
+		{
+			px_debug("parse_literal_data: data type=%c", type);
+			return PXE_PGP_NOT_TEXT;
+		}
+
+	ctx->unicode_mode = (type == 'u') ? 1 : 0;
+
+	/* read data */
+	while (1)
+	{
+		res = pullf_read(pkt, 32 * 1024, &buf);
+		if (res <= 0)
+			break;
+
+		if (ctx->text_mode && ctx->convert_crlf)
+			res = copy_crlf(dst, buf, res, &got_cr);
+		else
+			res = mbuf_append(dst, buf, res);
+		if (res < 0)
+			break;
+	}
+	if (res >= 0 && got_cr)
+		res = mbuf_append(dst, (const uint8 *) "\r", 1);
+	return res;
+}
+
+/* process_data_packets and parse_compressed_data call each other */
+static int process_data_packets(PGP_Context *ctx, MBuf *dst,
+					 PullFilter *src, int allow_compr, int need_mdc);
+
+static int
+parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
+{
+	int			res;
+	uint8		type;
+	PullFilter *pf_decompr;
+
+	GETBYTE(pkt, type);
+
+	ctx->compress_algo = type;
+	switch (type)
+	{
+		case PGP_COMPR_NONE:
+			res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
+			break;
+
+		case PGP_COMPR_ZIP:
+		case PGP_COMPR_ZLIB:
+			res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
+			if (res >= 0)
+			{
+				res = process_data_packets(ctx, dst, pf_decompr,
+										   NO_COMPR, NO_MDC);
+				pullf_free(pf_decompr);
+			}
+			break;
+
+		case PGP_COMPR_BZIP2:
+			px_debug("parse_compressed_data: bzip2 unsupported");
+			res = PXE_PGP_UNSUPPORTED_COMPR;
+			break;
+
+		default:
+			px_debug("parse_compressed_data: unknown compr type");
+			res = PXE_PGP_CORRUPT_DATA;
+	}
+
+	return res;
+}
+
+static int
+process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
+					 int allow_compr, int need_mdc)
+{
+	uint8		tag;
+	int			len,
+				res;
+	int			got_data = 0;
+	int			got_mdc = 0;
+	PullFilter *pkt = NULL;
+	uint8	   *tmp;
+
+	while (1)
+	{
+		res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
+		if (res <= 0)
+			break;
+
+
+		/* mdc packet should be last */
+		if (got_mdc)
+		{
+			px_debug("process_data_packets: data after mdc");
+			res = PXE_PGP_CORRUPT_DATA;
+			break;
+		}
+
+		/* context length inside SYMENC_MDC needs special handling */
+		if (need_mdc && res == PKT_CONTEXT)
+			res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
+		else
+			res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
+		if (res < 0)
+			break;
+
+		switch (tag)
+		{
+			case PGP_PKT_LITERAL_DATA:
+				got_data = 1;
+				res = parse_literal_data(ctx, dst, pkt);
+				break;
+			case PGP_PKT_COMPRESSED_DATA:
+				if (allow_compr == 0)
+				{
+					px_debug("process_data_packets: unexpected compression");
+					res = PXE_PGP_CORRUPT_DATA;
+				}
+				else if (got_data)
+				{
+					/*
+					 * compr data must be alone
+					 */
+					px_debug("process_data_packets: only one cmpr pkt allowed");
+					res = PXE_PGP_CORRUPT_DATA;
+				}
+				else
+				{
+					got_data = 1;
+					res = parse_compressed_data(ctx, dst, pkt);
+				}
+				break;
+			case PGP_PKT_MDC:
+				if (need_mdc == NO_MDC)
+				{
+					px_debug("process_data_packets: unexpected MDC");
+					res = PXE_PGP_CORRUPT_DATA;
+					break;
+				}
+
+				/* notify mdc_filter */
+				ctx->in_mdc_pkt = 1;
+
+				res = pullf_read(pkt, 8192, &tmp);
+				if (res > 0)
+					got_mdc = 1;
+				break;
+			default:
+				px_debug("process_data_packets: unexpected pkt tag=%d", tag);
+				res = PXE_PGP_CORRUPT_DATA;
+		}
+
+		pullf_free(pkt);
+		pkt = NULL;
+
+		if (res < 0)
+			break;
+	}
+
+	if (pkt)
+		pullf_free(pkt);
+
+	if (res < 0)
+		return res;
+
+	if (!got_data)
+	{
+		px_debug("process_data_packets: no data");
+		res = PXE_PGP_CORRUPT_DATA;
+	}
+	if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
+	{
+		px_debug("process_data_packets: got no mdc");
+		res = PXE_PGP_CORRUPT_DATA;
+	}
+	return res;
+}
+
+static int
+parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
+{
+	int			res;
+	PGP_CFB    *cfb = NULL;
+	PullFilter *pf_decrypt = NULL;
+	PullFilter *pf_prefix = NULL;
+
+	res = pgp_cfb_create(&cfb, ctx->cipher_algo,
+						 ctx->sess_key, ctx->sess_key_len, 1, NULL);
+	if (res < 0)
+		goto out;
+
+	res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
+	if (res < 0)
+		goto out;
+
+	res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
+	if (res < 0)
+		goto out;
+
+	res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
+
+out:
+	if (pf_prefix)
+		pullf_free(pf_prefix);
+	if (pf_decrypt)
+		pullf_free(pf_decrypt);
+	if (cfb)
+		pgp_cfb_free(cfb);
+
+	return res;
+}
+
+static int
+parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
+{
+	int			res;
+	PGP_CFB    *cfb = NULL;
+	PullFilter *pf_decrypt = NULL;
+	PullFilter *pf_prefix = NULL;
+	PullFilter *pf_mdc = NULL;
+	uint8		ver;
+
+	GETBYTE(pkt, ver);
+	if (ver != 1)
+	{
+		px_debug("parse_symenc_mdc_data: pkt ver != 1");
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	res = pgp_cfb_create(&cfb, ctx->cipher_algo,
+						 ctx->sess_key, ctx->sess_key_len, 0, NULL);
+	if (res < 0)
+		goto out;
+
+	res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
+	if (res < 0)
+		goto out;
+
+	res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
+	if (res < 0)
+		goto out;
+
+	res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
+	if (res < 0)
+		goto out;
+
+	res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
+
+out:
+	if (pf_prefix)
+		pullf_free(pf_prefix);
+	if (pf_mdc)
+		pullf_free(pf_mdc);
+	if (pf_decrypt)
+		pullf_free(pf_decrypt);
+	if (cfb)
+		pgp_cfb_free(cfb);
+
+	return res;
+}
+
+/*
+ * skip over packet contents
+ */
+int
+pgp_skip_packet(PullFilter *pkt)
+{
+	int			res = 1;
+	uint8	   *tmp;
+
+	while (res > 0)
+		res = pullf_read(pkt, 32 * 1024, &tmp);
+	return res < 0 ? res : 0;
+}
+
+/*
+ * expect to be at packet end, any data is error
+ */
+int
+pgp_expect_packet_end(PullFilter *pkt)
+{
+	int			res = 1;
+	uint8	   *tmp;
+
+	while (res > 0)
+	{
+		res = pullf_read(pkt, 32 * 1024, &tmp);
+		if (res > 0)
+		{
+			px_debug("pgp_expect_packet_end: got data");
+			return PXE_PGP_CORRUPT_DATA;
+		}
+	}
+	return res < 0 ? res : 0;
+}
+
+int
+pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
+{
+	int			res;
+	PullFilter *src = NULL;
+	PullFilter *pkt = NULL;
+	uint8		tag;
+	int			len;
+	int			got_key = 0;
+	int			got_data = 0;
+
+	res = pullf_create_mbuf_reader(&src, msrc);
+
+	while (res >= 0)
+	{
+		res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
+		if (res <= 0)
+			break;
+
+		res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
+		if (res < 0)
+			break;
+
+		res = PXE_PGP_CORRUPT_DATA;
+		switch (tag)
+		{
+			case PGP_PKT_MARKER:
+				res = pgp_skip_packet(pkt);
+				break;
+			case PGP_PKT_PUBENCRYPTED_SESSKEY:
+				/* fixme: skip those */
+				res = pgp_parse_pubenc_sesskey(ctx, pkt);
+				got_key = 1;
+				break;
+			case PGP_PKT_SYMENCRYPTED_SESSKEY:
+				if (got_key)
+
+					/*
+					 * Theoretically, there could be several keys, both public
+					 * and symmetric, all of which encrypt same session key.
+					 * Decrypt should try with each one, before failing.
+					 */
+					px_debug("pgp_decrypt: using first of several keys");
+				else
+				{
+					got_key = 1;
+					res = parse_symenc_sesskey(ctx, pkt);
+				}
+				break;
+			case PGP_PKT_SYMENCRYPTED_DATA:
+				if (!got_key)
+					px_debug("pgp_decrypt: have data but no key");
+				else if (got_data)
+					px_debug("pgp_decrypt: got second data packet");
+				else
+				{
+					got_data = 1;
+					ctx->disable_mdc = 1;
+					res = parse_symenc_data(ctx, pkt, mdst);
+				}
+				break;
+			case PGP_PKT_SYMENCRYPTED_DATA_MDC:
+				if (!got_key)
+					px_debug("pgp_decrypt: have data but no key");
+				else if (got_data)
+					px_debug("pgp_decrypt: several data pkts not supported");
+				else
+				{
+					got_data = 1;
+					ctx->disable_mdc = 0;
+					res = parse_symenc_mdc_data(ctx, pkt, mdst);
+				}
+				break;
+			default:
+				px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
+		}
+		pullf_free(pkt);
+		pkt = NULL;
+	}
+
+	if (pkt)
+		pullf_free(pkt);
+
+	if (src)
+		pullf_free(src);
+
+	if (res < 0)
+		return res;
+
+	if (!got_data || ctx->corrupt_prefix)
+		res = PXE_PGP_CORRUPT_DATA;
+
+	return res;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-encrypt.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-encrypt.c b/contrib/pgcrypto/pgp-encrypt.c
new file mode 100644
index 0000000..3b9b5d2
--- /dev/null
+++ b/contrib/pgcrypto/pgp-encrypt.c
@@ -0,0 +1,708 @@
+/*
+ * pgp-encrypt.c
+ *	  OpenPGP encrypt.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-encrypt.c
+ */
+
+#include "postgres.h"
+
+#include <time.h>
+
+#include "mbuf.h"
+#include "px.h"
+#include "pgp.h"
+
+
+#define MDC_DIGEST_LEN 20
+#define STREAM_ID 0xE0
+#define STREAM_BLOCK_SHIFT	14
+
+static uint8 *
+render_newlen(uint8 *h, int len)
+{
+	if (len <= 191)
+	{
+		*h++ = len & 255;
+	}
+	else if (len > 191 && len <= 8383)
+	{
+		*h++ = ((len - 192) >> 8) + 192;
+		*h++ = (len - 192) & 255;
+	}
+	else
+	{
+		*h++ = 255;
+		*h++ = (len >> 24) & 255;
+		*h++ = (len >> 16) & 255;
+		*h++ = (len >> 8) & 255;
+		*h++ = len & 255;
+	}
+	return h;
+}
+
+static int
+write_tag_only(PushFilter *dst, int tag)
+{
+	uint8		hdr = 0xC0 | tag;
+
+	return pushf_write(dst, &hdr, 1);
+}
+
+static int
+write_normal_header(PushFilter *dst, int tag, int len)
+{
+	uint8		hdr[8];
+	uint8	   *h = hdr;
+
+	*h++ = 0xC0 | tag;
+	h = render_newlen(h, len);
+	return pushf_write(dst, hdr, h - hdr);
+}
+
+
+/*
+ * MAC writer
+ */
+
+static int
+mdc_init(PushFilter *dst, void *init_arg, void **priv_p)
+{
+	int			res;
+	PX_MD	   *md;
+
+	res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
+	if (res < 0)
+		return res;
+
+	*priv_p = md;
+	return 0;
+}
+
+static int
+mdc_write(PushFilter *dst, void *priv, const uint8 *data, int len)
+{
+	PX_MD	   *md = priv;
+
+	px_md_update(md, data, len);
+	return pushf_write(dst, data, len);
+}
+
+static int
+mdc_flush(PushFilter *dst, void *priv)
+{
+	int			res;
+	uint8		pkt[2 + MDC_DIGEST_LEN];
+	PX_MD	   *md = priv;
+
+	/*
+	 * create mdc pkt
+	 */
+	pkt[0] = 0xD3;
+	pkt[1] = 0x14;				/* MDC_DIGEST_LEN */
+	px_md_update(md, pkt, 2);
+	px_md_finish(md, pkt + 2);
+
+	res = pushf_write(dst, pkt, 2 + MDC_DIGEST_LEN);
+	memset(pkt, 0, 2 + MDC_DIGEST_LEN);
+	return res;
+}
+
+static void
+mdc_free(void *priv)
+{
+	PX_MD	   *md = priv;
+
+	px_md_free(md);
+}
+
+static const PushFilterOps mdc_filter = {
+	mdc_init, mdc_write, mdc_flush, mdc_free
+};
+
+
+/*
+ * Encrypted pkt writer
+ */
+#define ENCBUF 8192
+struct EncStat
+{
+	PGP_CFB    *ciph;
+	uint8		buf[ENCBUF];
+};
+
+static int
+encrypt_init(PushFilter *next, void *init_arg, void **priv_p)
+{
+	struct EncStat *st;
+	PGP_Context *ctx = init_arg;
+	PGP_CFB    *ciph;
+	int			resync = 1;
+	int			res;
+
+	/* should we use newer packet format? */
+	if (ctx->disable_mdc == 0)
+	{
+		uint8		ver = 1;
+
+		resync = 0;
+		res = pushf_write(next, &ver, 1);
+		if (res < 0)
+			return res;
+	}
+	res = pgp_cfb_create(&ciph, ctx->cipher_algo,
+						 ctx->sess_key, ctx->sess_key_len, resync, NULL);
+	if (res < 0)
+		return res;
+
+	st = px_alloc(sizeof(*st));
+	memset(st, 0, sizeof(*st));
+	st->ciph = ciph;
+
+	*priv_p = st;
+	return ENCBUF;
+}
+
+static int
+encrypt_process(PushFilter *next, void *priv, const uint8 *data, int len)
+{
+	int			res;
+	struct EncStat *st = priv;
+	int			avail = len;
+
+	while (avail > 0)
+	{
+		int			tmplen = avail > ENCBUF ? ENCBUF : avail;
+
+		res = pgp_cfb_encrypt(st->ciph, data, tmplen, st->buf);
+		if (res < 0)
+			return res;
+
+		res = pushf_write(next, st->buf, tmplen);
+		if (res < 0)
+			return res;
+
+		data += tmplen;
+		avail -= tmplen;
+	}
+	return 0;
+}
+
+static void
+encrypt_free(void *priv)
+{
+	struct EncStat *st = priv;
+
+	memset(st, 0, sizeof(*st));
+	px_free(st);
+}
+
+static const PushFilterOps encrypt_filter = {
+	encrypt_init, encrypt_process, NULL, encrypt_free
+};
+
+/*
+ * Write Streamable pkts
+ */
+
+struct PktStreamStat
+{
+	int			final_done;
+	int			pkt_block;
+};
+
+static int
+pkt_stream_init(PushFilter *next, void *init_arg, void **priv_p)
+{
+	struct PktStreamStat *st;
+
+	st = px_alloc(sizeof(*st));
+	st->final_done = 0;
+	st->pkt_block = 1 << STREAM_BLOCK_SHIFT;
+	*priv_p = st;
+
+	return st->pkt_block;
+}
+
+static int
+pkt_stream_process(PushFilter *next, void *priv, const uint8 *data, int len)
+{
+	int			res;
+	uint8		hdr[8];
+	uint8	   *h = hdr;
+	struct PktStreamStat *st = priv;
+
+	if (st->final_done)
+		return PXE_BUG;
+
+	if (len == st->pkt_block)
+		*h++ = STREAM_ID | STREAM_BLOCK_SHIFT;
+	else
+	{
+		h = render_newlen(h, len);
+		st->final_done = 1;
+	}
+
+	res = pushf_write(next, hdr, h - hdr);
+	if (res < 0)
+		return res;
+
+	return pushf_write(next, data, len);
+}
+
+static int
+pkt_stream_flush(PushFilter *next, void *priv)
+{
+	int			res;
+	uint8		hdr[8];
+	uint8	   *h = hdr;
+	struct PktStreamStat *st = priv;
+
+	/* stream MUST end with normal packet. */
+	if (!st->final_done)
+	{
+		h = render_newlen(h, 0);
+		res = pushf_write(next, hdr, h - hdr);
+		if (res < 0)
+			return res;
+		st->final_done = 1;
+	}
+	return 0;
+}
+
+static void
+pkt_stream_free(void *priv)
+{
+	struct PktStreamStat *st = priv;
+
+	memset(st, 0, sizeof(*st));
+	px_free(st);
+}
+
+static const PushFilterOps pkt_stream_filter = {
+	pkt_stream_init, pkt_stream_process, pkt_stream_flush, pkt_stream_free
+};
+
+int
+pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p)
+{
+	int			res;
+
+	res = write_tag_only(dst, tag);
+	if (res < 0)
+		return res;
+
+	return pushf_create(res_p, &pkt_stream_filter, NULL, dst);
+}
+
+/*
+ * Text conversion filter
+ */
+
+static int
+crlf_process(PushFilter *dst, void *priv, const uint8 *data, int len)
+{
+	const uint8 *data_end = data + len;
+	const uint8 *p2,
+			   *p1 = data;
+	int			line_len;
+	static const uint8 crlf[] = {'\r', '\n'};
+	int			res = 0;
+
+	while (p1 < data_end)
+	{
+		p2 = memchr(p1, '\n', data_end - p1);
+		if (p2 == NULL)
+			p2 = data_end;
+
+		line_len = p2 - p1;
+
+		/* write data */
+		res = 0;
+		if (line_len > 0)
+		{
+			res = pushf_write(dst, p1, line_len);
+			if (res < 0)
+				break;
+			p1 += line_len;
+		}
+
+		/* write crlf */
+		while (p1 < data_end && *p1 == '\n')
+		{
+			res = pushf_write(dst, crlf, 2);
+			if (res < 0)
+				break;
+			p1++;
+		}
+	}
+	return res;
+}
+
+static const PushFilterOps crlf_filter = {
+	NULL, crlf_process, NULL, NULL
+};
+
+/*
+ * Initialize literal data packet
+ */
+static int
+init_litdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
+{
+	int			res;
+	int			hdrlen;
+	uint8		hdr[6];
+	uint32		t;
+	PushFilter *pkt;
+	int			type;
+
+	/*
+	 * Create header
+	 */
+
+	if (ctx->text_mode)
+		type = ctx->unicode_mode ? 'u' : 't';
+	else
+		type = 'b';
+
+	/*
+	 * Store the creation time into packet. The goal is to have as few known
+	 * bytes as possible.
+	 */
+	t = (uint32) time(NULL);
+
+	hdr[0] = type;
+	hdr[1] = 0;
+	hdr[2] = (t >> 24) & 255;
+	hdr[3] = (t >> 16) & 255;
+	hdr[4] = (t >> 8) & 255;
+	hdr[5] = t & 255;
+	hdrlen = 6;
+
+	res = write_tag_only(dst, PGP_PKT_LITERAL_DATA);
+	if (res < 0)
+		return res;
+
+	res = pushf_create(&pkt, &pkt_stream_filter, ctx, dst);
+	if (res < 0)
+		return res;
+
+	res = pushf_write(pkt, hdr, hdrlen);
+	if (res < 0)
+	{
+		pushf_free(pkt);
+		return res;
+	}
+
+	*pf_res = pkt;
+	return 0;
+}
+
+/*
+ * Initialize compression filter
+ */
+static int
+init_compress(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
+{
+	int			res;
+	uint8		type = ctx->compress_algo;
+	PushFilter *pkt;
+
+	res = write_tag_only(dst, PGP_PKT_COMPRESSED_DATA);
+	if (res < 0)
+		return res;
+
+	res = pushf_create(&pkt, &pkt_stream_filter, ctx, dst);
+	if (res < 0)
+		return res;
+
+	res = pushf_write(pkt, &type, 1);
+	if (res >= 0)
+		res = pgp_compress_filter(pf_res, ctx, pkt);
+
+	if (res < 0)
+		pushf_free(pkt);
+
+	return res;
+}
+
+/*
+ * Initialize encdata packet
+ */
+static int
+init_encdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
+{
+	int			res;
+	int			tag;
+
+	if (ctx->disable_mdc)
+		tag = PGP_PKT_SYMENCRYPTED_DATA;
+	else
+		tag = PGP_PKT_SYMENCRYPTED_DATA_MDC;
+
+	res = write_tag_only(dst, tag);
+	if (res < 0)
+		return res;
+
+	return pushf_create(pf_res, &pkt_stream_filter, ctx, dst);
+}
+
+/*
+ * write prefix
+ */
+static int
+write_prefix(PGP_Context *ctx, PushFilter *dst)
+{
+	uint8		prefix[PGP_MAX_BLOCK + 2];
+	int			res,
+				bs;
+
+	bs = pgp_get_cipher_block_size(ctx->cipher_algo);
+	res = px_get_random_bytes(prefix, bs);
+	if (res < 0)
+		return res;
+
+	prefix[bs + 0] = prefix[bs - 2];
+	prefix[bs + 1] = prefix[bs - 1];
+
+	res = pushf_write(dst, prefix, bs + 2);
+	memset(prefix, 0, bs + 2);
+	return res < 0 ? res : 0;
+}
+
+/*
+ * write symmetrically encrypted session key packet
+ */
+
+static int
+symencrypt_sesskey(PGP_Context *ctx, uint8 *dst)
+{
+	int			res;
+	PGP_CFB    *cfb;
+	uint8		algo = ctx->cipher_algo;
+
+	res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
+						 ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
+	if (res < 0)
+		return res;
+
+	pgp_cfb_encrypt(cfb, &algo, 1, dst);
+	pgp_cfb_encrypt(cfb, ctx->sess_key, ctx->sess_key_len, dst + 1);
+
+	pgp_cfb_free(cfb);
+	return ctx->sess_key_len + 1;
+}
+
+/* 5.3: Symmetric-Key Encrypted Session-Key */
+static int
+write_symenc_sesskey(PGP_Context *ctx, PushFilter *dst)
+{
+	uint8		pkt[256];
+	int			pktlen;
+	int			res;
+	uint8	   *p = pkt;
+
+	*p++ = 4;					/* 5.3 - version number  */
+	*p++ = ctx->s2k_cipher_algo;
+
+	*p++ = ctx->s2k.mode;
+	*p++ = ctx->s2k.digest_algo;
+	if (ctx->s2k.mode > 0)
+	{
+		memcpy(p, ctx->s2k.salt, 8);
+		p += 8;
+	}
+	if (ctx->s2k.mode == 3)
+		*p++ = ctx->s2k.iter;
+
+	if (ctx->use_sess_key)
+	{
+		res = symencrypt_sesskey(ctx, p);
+		if (res < 0)
+			return res;
+		p += res;
+	}
+
+	pktlen = p - pkt;
+	res = write_normal_header(dst, PGP_PKT_SYMENCRYPTED_SESSKEY, pktlen);
+	if (res >= 0)
+		res = pushf_write(dst, pkt, pktlen);
+
+	memset(pkt, 0, pktlen);
+	return res;
+}
+
+/*
+ * key setup
+ */
+static int
+init_s2k_key(PGP_Context *ctx)
+{
+	int			res;
+
+	if (ctx->s2k_cipher_algo < 0)
+		ctx->s2k_cipher_algo = ctx->cipher_algo;
+
+	res = pgp_s2k_fill(&ctx->s2k, ctx->s2k_mode, ctx->s2k_digest_algo);
+	if (res < 0)
+		return res;
+
+	return pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
+						   ctx->sym_key, ctx->sym_key_len);
+}
+
+static int
+init_sess_key(PGP_Context *ctx)
+{
+	int			res;
+
+	if (ctx->use_sess_key || ctx->pub_key)
+	{
+		ctx->sess_key_len = pgp_get_cipher_key_size(ctx->cipher_algo);
+		res = px_get_random_bytes(ctx->sess_key, ctx->sess_key_len);
+		if (res < 0)
+			return res;
+	}
+	else
+	{
+		ctx->sess_key_len = ctx->s2k.key_len;
+		memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
+	}
+
+	return 0;
+}
+
+/*
+ * combine
+ */
+int
+pgp_encrypt(PGP_Context *ctx, MBuf *src, MBuf *dst)
+{
+	int			res;
+	int			len;
+	uint8	   *buf;
+	PushFilter *pf,
+			   *pf_tmp;
+
+	/*
+	 * do we have any key
+	 */
+	if (!ctx->sym_key && !ctx->pub_key)
+		return PXE_ARGUMENT_ERROR;
+
+	/* MBuf writer */
+	res = pushf_create_mbuf_writer(&pf, dst);
+	if (res < 0)
+		goto out;
+
+	/*
+	 * initialize symkey
+	 */
+	if (ctx->sym_key)
+	{
+		res = init_s2k_key(ctx);
+		if (res < 0)
+			goto out;
+	}
+
+	res = init_sess_key(ctx);
+	if (res < 0)
+		goto out;
+
+	/*
+	 * write keypkt
+	 */
+	if (ctx->pub_key)
+		res = pgp_write_pubenc_sesskey(ctx, pf);
+	else
+		res = write_symenc_sesskey(ctx, pf);
+	if (res < 0)
+		goto out;
+
+	/* encrypted data pkt */
+	res = init_encdata_packet(&pf_tmp, ctx, pf);
+	if (res < 0)
+		goto out;
+	pf = pf_tmp;
+
+	/* encrypter */
+	res = pushf_create(&pf_tmp, &encrypt_filter, ctx, pf);
+	if (res < 0)
+		goto out;
+	pf = pf_tmp;
+
+	/* hasher */
+	if (ctx->disable_mdc == 0)
+	{
+		res = pushf_create(&pf_tmp, &mdc_filter, ctx, pf);
+		if (res < 0)
+			goto out;
+		pf = pf_tmp;
+	}
+
+	/* prefix */
+	res = write_prefix(ctx, pf);
+	if (res < 0)
+		goto out;
+
+	/* compressor */
+	if (ctx->compress_algo > 0 && ctx->compress_level > 0)
+	{
+		res = init_compress(&pf_tmp, ctx, pf);
+		if (res < 0)
+			goto out;
+		pf = pf_tmp;
+	}
+
+	/* data streamer */
+	res = init_litdata_packet(&pf_tmp, ctx, pf);
+	if (res < 0)
+		goto out;
+	pf = pf_tmp;
+
+
+	/* text conversion? */
+	if (ctx->text_mode && ctx->convert_crlf)
+	{
+		res = pushf_create(&pf_tmp, &crlf_filter, ctx, pf);
+		if (res < 0)
+			goto out;
+		pf = pf_tmp;
+	}
+
+	/*
+	 * chain complete
+	 */
+
+	len = mbuf_grab(src, mbuf_avail(src), &buf);
+	res = pushf_write(pf, buf, len);
+	if (res >= 0)
+		res = pushf_flush(pf);
+out:
+	pushf_free_all(pf);
+	return res;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-info.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-info.c b/contrib/pgcrypto/pgp-info.c
new file mode 100644
index 0000000..b75266f
--- /dev/null
+++ b/contrib/pgcrypto/pgp-info.c
@@ -0,0 +1,235 @@
+/*
+ * pgp-info.c
+ *	  Provide info about PGP data.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-info.c
+ */
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+static int
+read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf)
+{
+	int			res;
+	PGP_PubKey *pk = NULL;
+
+	res = _pgp_read_public_key(pkt, &pk);
+	if (res < 0)
+		goto err;
+
+	/* skip secret key part, if it exists */
+	res = pgp_skip_packet(pkt);
+	if (res < 0)
+		goto err;
+
+	/* is it encryption key */
+	switch (pk->algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			memcpy(keyid_buf, pk->key_id, 8);
+			res = 1;
+			break;
+		default:
+			res = 0;
+	}
+
+err:
+	pgp_key_free(pk);
+	return res;
+}
+
+static int
+read_pubenc_keyid(PullFilter *pkt, uint8 *keyid_buf)
+{
+	uint8		ver;
+	int			res;
+
+	GETBYTE(pkt, ver);
+	if (ver != 3)
+		return -1;
+
+	res = pullf_read_fixed(pkt, 8, keyid_buf);
+	if (res < 0)
+		return res;
+
+	return pgp_skip_packet(pkt);
+}
+
+static const char hextbl[] = "0123456789ABCDEF";
+
+static int
+print_key(uint8 *keyid, char *dst)
+{
+	int			i;
+	unsigned	c;
+
+	for (i = 0; i < 8; i++)
+	{
+		c = keyid[i];
+		*dst++ = hextbl[(c >> 4) & 0x0F];
+		*dst++ = hextbl[c & 0x0F];
+	}
+	*dst = 0;
+	return 8 * 2;
+}
+
+static const uint8 any_key[] =
+{0, 0, 0, 0, 0, 0, 0, 0};
+
+/*
+ * dst should have room for 17 bytes
+ */
+int
+pgp_get_keyid(MBuf *pgp_data, char *dst)
+{
+	int			res;
+	PullFilter *src;
+	PullFilter *pkt = NULL;
+	int			len;
+	uint8		tag;
+	int			got_pub_key = 0,
+				got_symenc_key = 0,
+				got_pubenc_key = 0;
+	int			got_data = 0;
+	uint8		keyid_buf[8];
+	int			got_main_key = 0;
+
+
+	res = pullf_create_mbuf_reader(&src, pgp_data);
+	if (res < 0)
+		return res;
+
+	while (1)
+	{
+		res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
+		if (res <= 0)
+			break;
+		res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
+		if (res < 0)
+			break;
+
+		switch (tag)
+		{
+			case PGP_PKT_SECRET_KEY:
+			case PGP_PKT_PUBLIC_KEY:
+				/* main key is for signing, so ignore it */
+				if (!got_main_key)
+				{
+					got_main_key = 1;
+					res = pgp_skip_packet(pkt);
+				}
+				else
+					res = PXE_PGP_MULTIPLE_KEYS;
+				break;
+			case PGP_PKT_SECRET_SUBKEY:
+			case PGP_PKT_PUBLIC_SUBKEY:
+				res = read_pubkey_keyid(pkt, keyid_buf);
+				if (res < 0)
+					break;
+				if (res > 0)
+					got_pub_key++;
+				break;
+			case PGP_PKT_PUBENCRYPTED_SESSKEY:
+				got_pubenc_key++;
+				res = read_pubenc_keyid(pkt, keyid_buf);
+				break;
+			case PGP_PKT_SYMENCRYPTED_DATA:
+			case PGP_PKT_SYMENCRYPTED_DATA_MDC:
+				/* don't skip it, just stop */
+				got_data = 1;
+				break;
+			case PGP_PKT_SYMENCRYPTED_SESSKEY:
+				got_symenc_key++;
+				/* fallthru */
+			case PGP_PKT_SIGNATURE:
+			case PGP_PKT_MARKER:
+			case PGP_PKT_TRUST:
+			case PGP_PKT_USER_ID:
+			case PGP_PKT_USER_ATTR:
+			case PGP_PKT_PRIV_61:
+				res = pgp_skip_packet(pkt);
+				break;
+			default:
+				res = PXE_PGP_CORRUPT_DATA;
+		}
+
+		if (pkt)
+			pullf_free(pkt);
+		pkt = NULL;
+
+		if (res < 0 || got_data)
+			break;
+	}
+
+	pullf_free(src);
+	if (pkt)
+		pullf_free(pkt);
+
+	if (res < 0)
+		return res;
+
+	/* now check sanity */
+	if (got_pub_key && got_pubenc_key)
+		res = PXE_PGP_CORRUPT_DATA;
+
+	if (got_pub_key > 1)
+		res = PXE_PGP_MULTIPLE_KEYS;
+
+	if (got_pubenc_key > 1)
+		res = PXE_PGP_MULTIPLE_KEYS;
+
+	/*
+	 * if still ok, look what we got
+	 */
+	if (res >= 0)
+	{
+		if (got_pubenc_key || got_pub_key)
+		{
+			if (memcmp(keyid_buf, any_key, 8) == 0)
+			{
+				memcpy(dst, "ANYKEY", 7);
+				res = 6;
+			}
+			else
+				res = print_key(keyid_buf, dst);
+		}
+		else if (got_symenc_key)
+		{
+			memcpy(dst, "SYMKEY", 7);
+			res = 6;
+		}
+		else
+			res = PXE_PGP_NO_USABLE_KEY;
+	}
+
+	return res;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-mpi-internal.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-mpi-internal.c b/contrib/pgcrypto/pgp-mpi-internal.c
new file mode 100644
index 0000000..d0e5830
--- /dev/null
+++ b/contrib/pgcrypto/pgp-mpi-internal.c
@@ -0,0 +1,308 @@
+/*
+ * pgp-mpi-internal.c
+ *	  OpenPGP MPI functions.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-mpi-internal.c
+ */
+#include "postgres.h"
+
+#include "imath.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+static mpz_t *
+mp_new()
+{
+	mpz_t	   *mp = mp_int_alloc();
+
+	mp_int_init_size(mp, 256);
+	return mp;
+}
+
+static void
+mp_clear_free(mpz_t *a)
+{
+	if (!a)
+		return;
+	/* fixme: no clear? */
+	mp_int_free(a);
+}
+
+
+static int
+mp_px_rand(uint32 bits, mpz_t *res)
+{
+	int			err;
+	unsigned	bytes = (bits + 7) / 8;
+	int			last_bits = bits & 7;
+	uint8	   *buf;
+
+	buf = px_alloc(bytes);
+	err = px_get_random_bytes(buf, bytes);
+	if (err < 0)
+	{
+		px_free(buf);
+		return err;
+	}
+
+	/* clear unnecessary bits and set last bit to one */
+	if (last_bits)
+	{
+		buf[0] >>= 8 - last_bits;
+		buf[0] |= 1 << (last_bits - 1);
+	}
+	else
+		buf[0] |= 1 << 7;
+
+	mp_int_read_unsigned(res, buf, bytes);
+
+	px_free(buf);
+
+	return 0;
+}
+
+static void
+mp_modmul(mpz_t *a, mpz_t *b, mpz_t *p, mpz_t *res)
+{
+	mpz_t	   *tmp = mp_new();
+
+	mp_int_mul(a, b, tmp);
+	mp_int_mod(tmp, p, res);
+	mp_clear_free(tmp);
+}
+
+static mpz_t *
+mpi_to_bn(PGP_MPI *n)
+{
+	mpz_t	   *bn = mp_new();
+
+	mp_int_read_unsigned(bn, n->data, n->bytes);
+
+	if (!bn)
+		return NULL;
+	if (mp_int_count_bits(bn) != n->bits)
+	{
+		px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d",
+				 n->bits, mp_int_count_bits(bn));
+		mp_clear_free(bn);
+		return NULL;
+	}
+	return bn;
+}
+
+static PGP_MPI *
+bn_to_mpi(mpz_t *bn)
+{
+	int			res;
+	PGP_MPI    *n;
+	int			bytes;
+
+	res = pgp_mpi_alloc(mp_int_count_bits(bn), &n);
+	if (res < 0)
+		return NULL;
+
+	bytes = (mp_int_count_bits(bn) + 7) / 8;
+	if (bytes != n->bytes)
+	{
+		px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d",
+				 bytes, n->bytes);
+		pgp_mpi_free(n);
+		return NULL;
+	}
+	mp_int_to_unsigned(bn, n->data, n->bytes);
+	return n;
+}
+
+/*
+ * Decide the number of bits in the random componont k
+ *
+ * It should be in the same range as p for signing (which
+ * is deprecated), but can be much smaller for encrypting.
+ *
+ * Until I research it further, I just mimic gpg behaviour.
+ * It has a special mapping table, for values <= 5120,
+ * above that it uses 'arbitrary high number'.	Following
+ * algorihm hovers 10-70 bits above gpg values.  And for
+ * larger p, it uses gpg's algorihm.
+ *
+ * The point is - if k gets large, encryption will be
+ * really slow.  It does not matter for decryption.
+ */
+static int
+decide_k_bits(int p_bits)
+{
+	if (p_bits <= 5120)
+		return p_bits / 10 + 160;
+	else
+		return (p_bits / 8 + 200) * 3 / 2;
+}
+
+int
+pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
+					PGP_MPI **c1_p, PGP_MPI **c2_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	int			k_bits;
+	mpz_t	   *m = mpi_to_bn(_m);
+	mpz_t	   *p = mpi_to_bn(pk->pub.elg.p);
+	mpz_t	   *g = mpi_to_bn(pk->pub.elg.g);
+	mpz_t	   *y = mpi_to_bn(pk->pub.elg.y);
+	mpz_t	   *k = mp_new();
+	mpz_t	   *yk = mp_new();
+	mpz_t	   *c1 = mp_new();
+	mpz_t	   *c2 = mp_new();
+
+	if (!m || !p || !g || !y || !k || !yk || !c1 || !c2)
+		goto err;
+
+	/*
+	 * generate k
+	 */
+	k_bits = decide_k_bits(mp_int_count_bits(p));
+	res = mp_px_rand(k_bits, k);
+	if (res < 0)
+		return res;
+
+	/*
+	 * c1 = g^k c2 = m * y^k
+	 */
+	mp_int_exptmod(g, k, p, c1);
+	mp_int_exptmod(y, k, p, yk);
+	mp_modmul(m, yk, p, c2);
+
+	/* result */
+	*c1_p = bn_to_mpi(c1);
+	*c2_p = bn_to_mpi(c2);
+	if (*c1_p && *c2_p)
+		res = 0;
+err:
+	mp_clear_free(c2);
+	mp_clear_free(c1);
+	mp_clear_free(yk);
+	mp_clear_free(k);
+	mp_clear_free(y);
+	mp_clear_free(g);
+	mp_clear_free(p);
+	mp_clear_free(m);
+	return res;
+}
+
+int
+pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
+					PGP_MPI **msg_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	mpz_t	   *c1 = mpi_to_bn(_c1);
+	mpz_t	   *c2 = mpi_to_bn(_c2);
+	mpz_t	   *p = mpi_to_bn(pk->pub.elg.p);
+	mpz_t	   *x = mpi_to_bn(pk->sec.elg.x);
+	mpz_t	   *c1x = mp_new();
+	mpz_t	   *div = mp_new();
+	mpz_t	   *m = mp_new();
+
+	if (!c1 || !c2 || !p || !x || !c1x || !div || !m)
+		goto err;
+
+	/*
+	 * m = c2 / (c1^x)
+	 */
+	mp_int_exptmod(c1, x, p, c1x);
+	mp_int_invmod(c1x, p, div);
+	mp_modmul(c2, div, p, m);
+
+	/* result */
+	*msg_p = bn_to_mpi(m);
+	if (*msg_p)
+		res = 0;
+err:
+	mp_clear_free(m);
+	mp_clear_free(div);
+	mp_clear_free(c1x);
+	mp_clear_free(x);
+	mp_clear_free(p);
+	mp_clear_free(c2);
+	mp_clear_free(c1);
+	return res;
+}
+
+int
+pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	mpz_t	   *m = mpi_to_bn(_m);
+	mpz_t	   *e = mpi_to_bn(pk->pub.rsa.e);
+	mpz_t	   *n = mpi_to_bn(pk->pub.rsa.n);
+	mpz_t	   *c = mp_new();
+
+	if (!m || !e || !n || !c)
+		goto err;
+
+	/*
+	 * c = m ^ e
+	 */
+	mp_int_exptmod(m, e, n, c);
+
+	*c_p = bn_to_mpi(c);
+	if (*c_p)
+		res = 0;
+err:
+	mp_clear_free(c);
+	mp_clear_free(n);
+	mp_clear_free(e);
+	mp_clear_free(m);
+	return res;
+}
+
+int
+pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	mpz_t	   *c = mpi_to_bn(_c);
+	mpz_t	   *d = mpi_to_bn(pk->sec.rsa.d);
+	mpz_t	   *n = mpi_to_bn(pk->pub.rsa.n);
+	mpz_t	   *m = mp_new();
+
+	if (!m || !d || !n || !c)
+		goto err;
+
+	/*
+	 * m = c ^ d
+	 */
+	mp_int_exptmod(c, d, n, m);
+
+	*m_p = bn_to_mpi(m);
+	if (*m_p)
+		res = 0;
+err:
+	mp_clear_free(m);
+	mp_clear_free(n);
+	mp_clear_free(d);
+	mp_clear_free(c);
+	return res;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-mpi-openssl.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-mpi-openssl.c b/contrib/pgcrypto/pgp-mpi-openssl.c
new file mode 100644
index 0000000..ed41e11
--- /dev/null
+++ b/contrib/pgcrypto/pgp-mpi-openssl.c
@@ -0,0 +1,285 @@
+/*
+ * pgp-mpi-openssl.c
+ *	  OpenPGP MPI functions using OpenSSL BIGNUM code.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-mpi-openssl.c
+ */
+#include "postgres.h"
+
+#include <openssl/bn.h>
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+static BIGNUM *
+mpi_to_bn(PGP_MPI *n)
+{
+	BIGNUM	   *bn = BN_bin2bn(n->data, n->bytes, NULL);
+
+	if (!bn)
+		return NULL;
+	if (BN_num_bits(bn) != n->bits)
+	{
+		px_debug("mpi_to_bn: bignum conversion failed: mpi=%d, bn=%d",
+				 n->bits, BN_num_bits(bn));
+		BN_clear_free(bn);
+		return NULL;
+	}
+	return bn;
+}
+
+static PGP_MPI *
+bn_to_mpi(BIGNUM *bn)
+{
+	int			res;
+	PGP_MPI    *n;
+
+	res = pgp_mpi_alloc(BN_num_bits(bn), &n);
+	if (res < 0)
+		return NULL;
+
+	if (BN_num_bytes(bn) != n->bytes)
+	{
+		px_debug("bn_to_mpi: bignum conversion failed: bn=%d, mpi=%d",
+				 BN_num_bytes(bn), n->bytes);
+		pgp_mpi_free(n);
+		return NULL;
+	}
+	BN_bn2bin(bn, n->data);
+	return n;
+}
+
+/*
+ * Decide the number of bits in the random componont k
+ *
+ * It should be in the same range as p for signing (which
+ * is deprecated), but can be much smaller for encrypting.
+ *
+ * Until I research it further, I just mimic gpg behaviour.
+ * It has a special mapping table, for values <= 5120,
+ * above that it uses 'arbitrary high number'.	Following
+ * algorihm hovers 10-70 bits above gpg values.  And for
+ * larger p, it uses gpg's algorihm.
+ *
+ * The point is - if k gets large, encryption will be
+ * really slow.  It does not matter for decryption.
+ */
+static int
+decide_k_bits(int p_bits)
+{
+	if (p_bits <= 5120)
+		return p_bits / 10 + 160;
+	else
+		return (p_bits / 8 + 200) * 3 / 2;
+}
+
+int
+pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *_m,
+					PGP_MPI **c1_p, PGP_MPI **c2_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	int			k_bits;
+	BIGNUM	   *m = mpi_to_bn(_m);
+	BIGNUM	   *p = mpi_to_bn(pk->pub.elg.p);
+	BIGNUM	   *g = mpi_to_bn(pk->pub.elg.g);
+	BIGNUM	   *y = mpi_to_bn(pk->pub.elg.y);
+	BIGNUM	   *k = BN_new();
+	BIGNUM	   *yk = BN_new();
+	BIGNUM	   *c1 = BN_new();
+	BIGNUM	   *c2 = BN_new();
+	BN_CTX	   *tmp = BN_CTX_new();
+
+	if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp)
+		goto err;
+
+	/*
+	 * generate k
+	 */
+	k_bits = decide_k_bits(BN_num_bits(p));
+	if (!BN_rand(k, k_bits, 0, 0))
+		goto err;
+
+	/*
+	 * c1 = g^k c2 = m * y^k
+	 */
+	if (!BN_mod_exp(c1, g, k, p, tmp))
+		goto err;
+	if (!BN_mod_exp(yk, y, k, p, tmp))
+		goto err;
+	if (!BN_mod_mul(c2, m, yk, p, tmp))
+		goto err;
+
+	/* result */
+	*c1_p = bn_to_mpi(c1);
+	*c2_p = bn_to_mpi(c2);
+	if (*c1_p && *c2_p)
+		res = 0;
+err:
+	if (tmp)
+		BN_CTX_free(tmp);
+	if (c2)
+		BN_clear_free(c2);
+	if (c1)
+		BN_clear_free(c1);
+	if (yk)
+		BN_clear_free(yk);
+	if (k)
+		BN_clear_free(k);
+	if (y)
+		BN_clear_free(y);
+	if (g)
+		BN_clear_free(g);
+	if (p)
+		BN_clear_free(p);
+	if (m)
+		BN_clear_free(m);
+	return res;
+}
+
+int
+pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *_c1, PGP_MPI *_c2,
+					PGP_MPI **msg_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	BIGNUM	   *c1 = mpi_to_bn(_c1);
+	BIGNUM	   *c2 = mpi_to_bn(_c2);
+	BIGNUM	   *p = mpi_to_bn(pk->pub.elg.p);
+	BIGNUM	   *x = mpi_to_bn(pk->sec.elg.x);
+	BIGNUM	   *c1x = BN_new();
+	BIGNUM	   *div = BN_new();
+	BIGNUM	   *m = BN_new();
+	BN_CTX	   *tmp = BN_CTX_new();
+
+	if (!c1 || !c2 || !p || !x || !c1x || !div || !m || !tmp)
+		goto err;
+
+	/*
+	 * m = c2 / (c1^x)
+	 */
+	if (!BN_mod_exp(c1x, c1, x, p, tmp))
+		goto err;
+	if (!BN_mod_inverse(div, c1x, p, tmp))
+		goto err;
+	if (!BN_mod_mul(m, c2, div, p, tmp))
+		goto err;
+
+	/* result */
+	*msg_p = bn_to_mpi(m);
+	if (*msg_p)
+		res = 0;
+err:
+	if (tmp)
+		BN_CTX_free(tmp);
+	if (m)
+		BN_clear_free(m);
+	if (div)
+		BN_clear_free(div);
+	if (c1x)
+		BN_clear_free(c1x);
+	if (x)
+		BN_clear_free(x);
+	if (p)
+		BN_clear_free(p);
+	if (c2)
+		BN_clear_free(c2);
+	if (c1)
+		BN_clear_free(c1);
+	return res;
+}
+
+int
+pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *_m, PGP_MPI **c_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	BIGNUM	   *m = mpi_to_bn(_m);
+	BIGNUM	   *e = mpi_to_bn(pk->pub.rsa.e);
+	BIGNUM	   *n = mpi_to_bn(pk->pub.rsa.n);
+	BIGNUM	   *c = BN_new();
+	BN_CTX	   *tmp = BN_CTX_new();
+
+	if (!m || !e || !n || !c || !tmp)
+		goto err;
+
+	/*
+	 * c = m ^ e
+	 */
+	if (!BN_mod_exp(c, m, e, n, tmp))
+		goto err;
+
+	*c_p = bn_to_mpi(c);
+	if (*c_p)
+		res = 0;
+err:
+	if (tmp)
+		BN_CTX_free(tmp);
+	if (c)
+		BN_clear_free(c);
+	if (n)
+		BN_clear_free(n);
+	if (e)
+		BN_clear_free(e);
+	if (m)
+		BN_clear_free(m);
+	return res;
+}
+
+int
+pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *_c, PGP_MPI **m_p)
+{
+	int			res = PXE_PGP_MATH_FAILED;
+	BIGNUM	   *c = mpi_to_bn(_c);
+	BIGNUM	   *d = mpi_to_bn(pk->sec.rsa.d);
+	BIGNUM	   *n = mpi_to_bn(pk->pub.rsa.n);
+	BIGNUM	   *m = BN_new();
+	BN_CTX	   *tmp = BN_CTX_new();
+
+	if (!m || !d || !n || !c || !tmp)
+		goto err;
+
+	/*
+	 * m = c ^ d
+	 */
+	if (!BN_mod_exp(m, c, d, n, tmp))
+		goto err;
+
+	*m_p = bn_to_mpi(m);
+	if (*m_p)
+		res = 0;
+err:
+	if (tmp)
+		BN_CTX_free(tmp);
+	if (m)
+		BN_clear_free(m);
+	if (n)
+		BN_clear_free(n);
+	if (d)
+		BN_clear_free(d);
+	if (c)
+		BN_clear_free(c);
+	return res;
+}


[02/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sha2.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sha2.c b/contrib/pgcrypto/sha2.c
new file mode 100644
index 0000000..5de94b2
--- /dev/null
+++ b/contrib/pgcrypto/sha2.c
@@ -0,0 +1,991 @@
+/*	$OpenBSD: sha2.c,v 1.6 2004/05/03 02:57:36 millert Exp $	*/
+
+/*
+ * FILE:	sha2.c
+ * AUTHOR:	Aaron D. Gifford <me...@aarongifford.com>
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ *
+ * contrib/pgcrypto/sha2.c
+ */
+
+#include "postgres.h"
+
+#include <sys/param.h>
+
+#include "sha2.h"
+
+/*
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file).  Either define on the command line, for example:
+ *
+ *	 cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ *	 #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8)
+#define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16)
+#define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16)
+
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#ifndef WORDS_BIGENDIAN
+#define REVERSE32(w,x)	{ \
+	uint32 tmp = (w); \
+	tmp = (tmp >> 16) | (tmp << 16); \
+	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#define REVERSE64(w,x)	{ \
+	uint64 tmp = (w); \
+	tmp = (tmp >> 32) | (tmp << 32); \
+	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
+		  ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
+	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
+		  ((tmp & 0x0000ffff0000ffffULL) << 16); \
+}
+#endif   /* not bigendian */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n)	{ \
+	(w)[0] += (uint64)(n); \
+	if ((w)[0] < (n)) { \
+		(w)[1]++; \
+	} \
+}
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ *	 NOTE:	The naming of R and S appears backwards here (R is a SHIFT and
+ *	 S is a ROTATION) because the SHA-256/384/512 description document
+ *	 (see http://www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf)
+ *	 uses this same "backwards" definition.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define R(b,x)		((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-256: */
+#define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
+#define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
+#define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
+#define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
+#define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
+
+/*** INTERNAL FUNCTION PROTOTYPES *************************************/
+/* NOTE: These should not be accessed directly from outside this
+ * library -- they are intended for private internal visibility/use
+ * only.
+ */
+static void SHA512_Last(SHA512_CTX *);
+static void SHA256_Transform(SHA256_CTX *, const uint8 *);
+static void SHA512_Transform(SHA512_CTX *, const uint8 *);
+
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-256: */
+static const uint32 K256[64] = {
+	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Initial hash value H for SHA-224: */
+static const uint32 sha224_initial_hash_value[8] = {
+	0xc1059ed8UL,
+	0x367cd507UL,
+	0x3070dd17UL,
+	0xf70e5939UL,
+	0xffc00b31UL,
+	0x68581511UL,
+	0x64f98fa7UL,
+	0xbefa4fa4UL
+};
+
+/* Initial hash value H for SHA-256: */
+static const uint32 sha256_initial_hash_value[8] = {
+	0x6a09e667UL,
+	0xbb67ae85UL,
+	0x3c6ef372UL,
+	0xa54ff53aUL,
+	0x510e527fUL,
+	0x9b05688cUL,
+	0x1f83d9abUL,
+	0x5be0cd19UL
+};
+
+/* Hash constant words K for SHA-384 and SHA-512: */
+static const uint64 K512[80] = {
+	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* Initial hash value H for SHA-384 */
+static const uint64 sha384_initial_hash_value[8] = {
+	0xcbbb9d5dc1059ed8ULL,
+	0x629a292a367cd507ULL,
+	0x9159015a3070dd17ULL,
+	0x152fecd8f70e5939ULL,
+	0x67332667ffc00b31ULL,
+	0x8eb44a8768581511ULL,
+	0xdb0c2e0d64f98fa7ULL,
+	0x47b5481dbefa4fa4ULL
+};
+
+/* Initial hash value H for SHA-512 */
+static const uint64 sha512_initial_hash_value[8] = {
+	0x6a09e667f3bcc908ULL,
+	0xbb67ae8584caa73bULL,
+	0x3c6ef372fe94f82bULL,
+	0xa54ff53a5f1d36f1ULL,
+	0x510e527fade682d1ULL,
+	0x9b05688c2b3e6c1fULL,
+	0x1f83d9abfb41bd6bULL,
+	0x5be0cd19137e2179ULL
+};
+
+
+/*** SHA-256: *********************************************************/
+void
+SHA256_Init(SHA256_CTX *context)
+{
+	if (context == NULL)
+		return;
+	memcpy(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
+	memset(context->buffer, 0, SHA256_BLOCK_LENGTH);
+	context->bitcount = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do {					\
+	W256[j] = (uint32)data[3] | ((uint32)data[2] << 8) |		\
+		((uint32)data[1] << 16) | ((uint32)data[0] << 24);		\
+	data += 4;								\
+	T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
+	(d) += T1;								\
+	(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));			\
+	j++;									\
+} while(0)
+
+#define ROUND256(a,b,c,d,e,f,g,h) do {						\
+	s0 = W256[(j+1)&0x0f];							\
+	s0 = sigma0_256(s0);							\
+	s1 = W256[(j+14)&0x0f];							\
+	s1 = sigma1_256(s1);							\
+	T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] +		\
+		 (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);			\
+	(d) += T1;								\
+	(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));			\
+	j++;									\
+} while(0)
+
+static void
+SHA256_Transform(SHA256_CTX *context, const uint8 *data)
+{
+	uint32		a,
+				b,
+				c,
+				d,
+				e,
+				f,
+				g,
+				h,
+				s0,
+				s1;
+	uint32		T1,
+			   *W256;
+	int			j;
+
+	W256 = (uint32 *) context->buffer;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do
+	{
+		/* Rounds 0 to 15 (unrolled): */
+		ROUND256_0_TO_15(a, b, c, d, e, f, g, h);
+		ROUND256_0_TO_15(h, a, b, c, d, e, f, g);
+		ROUND256_0_TO_15(g, h, a, b, c, d, e, f);
+		ROUND256_0_TO_15(f, g, h, a, b, c, d, e);
+		ROUND256_0_TO_15(e, f, g, h, a, b, c, d);
+		ROUND256_0_TO_15(d, e, f, g, h, a, b, c);
+		ROUND256_0_TO_15(c, d, e, f, g, h, a, b);
+		ROUND256_0_TO_15(b, c, d, e, f, g, h, a);
+	} while (j < 16);
+
+	/* Now for the remaining rounds to 64: */
+	do
+	{
+		ROUND256(a, b, c, d, e, f, g, h);
+		ROUND256(h, a, b, c, d, e, f, g);
+		ROUND256(g, h, a, b, c, d, e, f);
+		ROUND256(f, g, h, a, b, c, d, e);
+		ROUND256(e, f, g, h, a, b, c, d);
+		ROUND256(d, e, f, g, h, a, b, c);
+		ROUND256(c, d, e, f, g, h, a, b);
+		ROUND256(b, c, d, e, f, g, h, a);
+	} while (j < 64);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+#else							/* SHA2_UNROLL_TRANSFORM */
+
+static void
+SHA256_Transform(SHA256_CTX *context, const uint8 *data)
+{
+	uint32		a,
+				b,
+				c,
+				d,
+				e,
+				f,
+				g,
+				h,
+				s0,
+				s1;
+	uint32		T1,
+				T2,
+			   *W256;
+	int			j;
+
+	W256 = (uint32 *) context->buffer;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do
+	{
+		W256[j] = (uint32) data[3] | ((uint32) data[2] << 8) |
+			((uint32) data[1] << 16) | ((uint32) data[0] << 24);
+		data += 4;
+		/* Apply the SHA-256 compression function to update a..h */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+		T2 = Sigma0_256(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 16);
+
+	do
+	{
+		/* Part of the message block expansion: */
+		s0 = W256[(j + 1) & 0x0f];
+		s0 = sigma0_256(s0);
+		s1 = W256[(j + 14) & 0x0f];
+		s1 = sigma1_256(s1);
+
+		/* Apply the SHA-256 compression function to update a..h */
+		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
+			(W256[j & 0x0f] += s1 + W256[(j + 9) & 0x0f] + s0);
+		T2 = Sigma0_256(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 64);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+#endif   /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA256_Update(SHA256_CTX *context, const uint8 *data, size_t len)
+{
+	size_t		freespace,
+				usedspace;
+
+	/* Calling with no data is valid (we do nothing) */
+	if (len == 0)
+		return;
+
+	usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+	if (usedspace > 0)
+	{
+		/* Calculate how much free space is available in the buffer */
+		freespace = SHA256_BLOCK_LENGTH - usedspace;
+
+		if (len >= freespace)
+		{
+			/* Fill the buffer completely and process it */
+			memcpy(&context->buffer[usedspace], data, freespace);
+			context->bitcount += freespace << 3;
+			len -= freespace;
+			data += freespace;
+			SHA256_Transform(context, context->buffer);
+		}
+		else
+		{
+			/* The buffer is not yet full */
+			memcpy(&context->buffer[usedspace], data, len);
+			context->bitcount += len << 3;
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len >= SHA256_BLOCK_LENGTH)
+	{
+		/* Process as many complete blocks as we can */
+		SHA256_Transform(context, data);
+		context->bitcount += SHA256_BLOCK_LENGTH << 3;
+		len -= SHA256_BLOCK_LENGTH;
+		data += SHA256_BLOCK_LENGTH;
+	}
+	if (len > 0)
+	{
+		/* There's left-overs, so save 'em */
+		memcpy(context->buffer, data, len);
+		context->bitcount += len << 3;
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+static void
+SHA256_Last(SHA256_CTX *context)
+{
+	unsigned int usedspace;
+
+	usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+#ifndef WORDS_BIGENDIAN
+	/* Convert FROM host byte order */
+	REVERSE64(context->bitcount, context->bitcount);
+#endif
+	if (usedspace > 0)
+	{
+		/* Begin padding with a 1 bit: */
+		context->buffer[usedspace++] = 0x80;
+
+		if (usedspace <= SHA256_SHORT_BLOCK_LENGTH)
+		{
+			/* Set-up for the last transform: */
+			memset(&context->buffer[usedspace], 0, SHA256_SHORT_BLOCK_LENGTH - usedspace);
+		}
+		else
+		{
+			if (usedspace < SHA256_BLOCK_LENGTH)
+			{
+				memset(&context->buffer[usedspace], 0, SHA256_BLOCK_LENGTH - usedspace);
+			}
+			/* Do second-to-last transform: */
+			SHA256_Transform(context, context->buffer);
+
+			/* And set-up for the last transform: */
+			memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
+		}
+	}
+	else
+	{
+		/* Set-up for the last transform: */
+		memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
+
+		/* Begin padding with a 1 bit: */
+		*context->buffer = 0x80;
+	}
+	/* Set the bit count: */
+	*(uint64 *) &context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+
+	/* Final transform: */
+	SHA256_Transform(context, context->buffer);
+}
+
+void
+SHA256_Final(uint8 digest[], SHA256_CTX *context)
+{
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != NULL)
+	{
+		SHA256_Last(context);
+
+#ifndef WORDS_BIGENDIAN
+		{
+			/* Convert TO host byte order */
+			int			j;
+
+			for (j = 0; j < 8; j++)
+			{
+				REVERSE32(context->state[j], context->state[j]);
+			}
+		}
+#endif
+		memcpy(digest, context->state, SHA256_DIGEST_LENGTH);
+	}
+
+	/* Clean up state data: */
+	memset(context, 0, sizeof(*context));
+}
+
+
+/*** SHA-512: *********************************************************/
+void
+SHA512_Init(SHA512_CTX *context)
+{
+	if (context == NULL)
+		return;
+	memcpy(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+	memset(context->buffer, 0, SHA512_BLOCK_LENGTH);
+	context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do {					\
+	W512[j] = (uint64)data[7] | ((uint64)data[6] << 8) |		\
+		((uint64)data[5] << 16) | ((uint64)data[4] << 24) |		\
+		((uint64)data[3] << 32) | ((uint64)data[2] << 40) |		\
+		((uint64)data[1] << 48) | ((uint64)data[0] << 56);		\
+	data += 8;								\
+	T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
+	(d) += T1;								\
+	(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c));			\
+	j++;									\
+} while(0)
+
+
+#define ROUND512(a,b,c,d,e,f,g,h) do {						\
+	s0 = W512[(j+1)&0x0f];							\
+	s0 = sigma0_512(s0);							\
+	s1 = W512[(j+14)&0x0f];							\
+	s1 = sigma1_512(s1);							\
+	T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] +		\
+			 (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);			\
+	(d) += T1;								\
+	(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c));			\
+	j++;									\
+} while(0)
+
+static void
+SHA512_Transform(SHA512_CTX *context, const uint8 *data)
+{
+	uint64		a,
+				b,
+				c,
+				d,
+				e,
+				f,
+				g,
+				h,
+				s0,
+				s1;
+	uint64		T1,
+			   *W512 = (uint64 *) context->buffer;
+	int			j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do
+	{
+		ROUND512_0_TO_15(a, b, c, d, e, f, g, h);
+		ROUND512_0_TO_15(h, a, b, c, d, e, f, g);
+		ROUND512_0_TO_15(g, h, a, b, c, d, e, f);
+		ROUND512_0_TO_15(f, g, h, a, b, c, d, e);
+		ROUND512_0_TO_15(e, f, g, h, a, b, c, d);
+		ROUND512_0_TO_15(d, e, f, g, h, a, b, c);
+		ROUND512_0_TO_15(c, d, e, f, g, h, a, b);
+		ROUND512_0_TO_15(b, c, d, e, f, g, h, a);
+	} while (j < 16);
+
+	/* Now for the remaining rounds up to 79: */
+	do
+	{
+		ROUND512(a, b, c, d, e, f, g, h);
+		ROUND512(h, a, b, c, d, e, f, g);
+		ROUND512(g, h, a, b, c, d, e, f);
+		ROUND512(f, g, h, a, b, c, d, e);
+		ROUND512(e, f, g, h, a, b, c, d);
+		ROUND512(d, e, f, g, h, a, b, c);
+		ROUND512(c, d, e, f, g, h, a, b);
+		ROUND512(b, c, d, e, f, g, h, a);
+	} while (j < 80);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = 0;
+}
+#else							/* SHA2_UNROLL_TRANSFORM */
+
+static void
+SHA512_Transform(SHA512_CTX *context, const uint8 *data)
+{
+	uint64		a,
+				b,
+				c,
+				d,
+				e,
+				f,
+				g,
+				h,
+				s0,
+				s1;
+	uint64		T1,
+				T2,
+			   *W512 = (uint64 *) context->buffer;
+	int			j;
+
+	/* Initialize registers with the prev. intermediate value */
+	a = context->state[0];
+	b = context->state[1];
+	c = context->state[2];
+	d = context->state[3];
+	e = context->state[4];
+	f = context->state[5];
+	g = context->state[6];
+	h = context->state[7];
+
+	j = 0;
+	do
+	{
+		W512[j] = (uint64) data[7] | ((uint64) data[6] << 8) |
+			((uint64) data[5] << 16) | ((uint64) data[4] << 24) |
+			((uint64) data[3] << 32) | ((uint64) data[2] << 40) |
+			((uint64) data[1] << 48) | ((uint64) data[0] << 56);
+		data += 8;
+		/* Apply the SHA-512 compression function to update a..h */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+		T2 = Sigma0_512(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 16);
+
+	do
+	{
+		/* Part of the message block expansion: */
+		s0 = W512[(j + 1) & 0x0f];
+		s0 = sigma0_512(s0);
+		s1 = W512[(j + 14) & 0x0f];
+		s1 = sigma1_512(s1);
+
+		/* Apply the SHA-512 compression function to update a..h */
+		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+			(W512[j & 0x0f] += s1 + W512[(j + 9) & 0x0f] + s0);
+		T2 = Sigma0_512(a) + Maj(a, b, c);
+		h = g;
+		g = f;
+		f = e;
+		e = d + T1;
+		d = c;
+		c = b;
+		b = a;
+		a = T1 + T2;
+
+		j++;
+	} while (j < 80);
+
+	/* Compute the current intermediate hash value */
+	context->state[0] += a;
+	context->state[1] += b;
+	context->state[2] += c;
+	context->state[3] += d;
+	context->state[4] += e;
+	context->state[5] += f;
+	context->state[6] += g;
+	context->state[7] += h;
+
+	/* Clean up */
+	a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+#endif   /* SHA2_UNROLL_TRANSFORM */
+
+void
+SHA512_Update(SHA512_CTX *context, const uint8 *data, size_t len)
+{
+	size_t		freespace,
+				usedspace;
+
+	/* Calling with no data is valid (we do nothing) */
+	if (len == 0)
+		return;
+
+	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+	if (usedspace > 0)
+	{
+		/* Calculate how much free space is available in the buffer */
+		freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+		if (len >= freespace)
+		{
+			/* Fill the buffer completely and process it */
+			memcpy(&context->buffer[usedspace], data, freespace);
+			ADDINC128(context->bitcount, freespace << 3);
+			len -= freespace;
+			data += freespace;
+			SHA512_Transform(context, context->buffer);
+		}
+		else
+		{
+			/* The buffer is not yet full */
+			memcpy(&context->buffer[usedspace], data, len);
+			ADDINC128(context->bitcount, len << 3);
+			/* Clean up: */
+			usedspace = freespace = 0;
+			return;
+		}
+	}
+	while (len >= SHA512_BLOCK_LENGTH)
+	{
+		/* Process as many complete blocks as we can */
+		SHA512_Transform(context, data);
+		ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+		len -= SHA512_BLOCK_LENGTH;
+		data += SHA512_BLOCK_LENGTH;
+	}
+	if (len > 0)
+	{
+		/* There's left-overs, so save 'em */
+		memcpy(context->buffer, data, len);
+		ADDINC128(context->bitcount, len << 3);
+	}
+	/* Clean up: */
+	usedspace = freespace = 0;
+}
+
+static void
+SHA512_Last(SHA512_CTX *context)
+{
+	unsigned int usedspace;
+
+	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+#ifndef WORDS_BIGENDIAN
+	/* Convert FROM host byte order */
+	REVERSE64(context->bitcount[0], context->bitcount[0]);
+	REVERSE64(context->bitcount[1], context->bitcount[1]);
+#endif
+	if (usedspace > 0)
+	{
+		/* Begin padding with a 1 bit: */
+		context->buffer[usedspace++] = 0x80;
+
+		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH)
+		{
+			/* Set-up for the last transform: */
+			memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace);
+		}
+		else
+		{
+			if (usedspace < SHA512_BLOCK_LENGTH)
+			{
+				memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
+			}
+			/* Do second-to-last transform: */
+			SHA512_Transform(context, context->buffer);
+
+			/* And set-up for the last transform: */
+			memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
+		}
+	}
+	else
+	{
+		/* Prepare for final transform: */
+		memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH);
+
+		/* Begin padding with a 1 bit: */
+		*context->buffer = 0x80;
+	}
+	/* Store the length of input data (in bits): */
+	*(uint64 *) &context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
+	*(uint64 *) &context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8] = context->bitcount[0];
+
+	/* Final transform: */
+	SHA512_Transform(context, context->buffer);
+}
+
+void
+SHA512_Final(uint8 digest[], SHA512_CTX *context)
+{
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != NULL)
+	{
+		SHA512_Last(context);
+
+		/* Save the hash data for output: */
+#ifndef WORDS_BIGENDIAN
+		{
+			/* Convert TO host byte order */
+			int			j;
+
+			for (j = 0; j < 8; j++)
+			{
+				REVERSE64(context->state[j], context->state[j]);
+			}
+		}
+#endif
+		memcpy(digest, context->state, SHA512_DIGEST_LENGTH);
+	}
+
+	/* Zero out state data */
+	memset(context, 0, sizeof(*context));
+}
+
+
+/*** SHA-384: *********************************************************/
+void
+SHA384_Init(SHA384_CTX *context)
+{
+	if (context == NULL)
+		return;
+	memcpy(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
+	memset(context->buffer, 0, SHA384_BLOCK_LENGTH);
+	context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+void
+SHA384_Update(SHA384_CTX *context, const uint8 *data, size_t len)
+{
+	SHA512_Update((SHA512_CTX *) context, data, len);
+}
+
+void
+SHA384_Final(uint8 digest[], SHA384_CTX *context)
+{
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != NULL)
+	{
+		SHA512_Last((SHA512_CTX *) context);
+
+		/* Save the hash data for output: */
+#ifndef WORDS_BIGENDIAN
+		{
+			/* Convert TO host byte order */
+			int			j;
+
+			for (j = 0; j < 6; j++)
+			{
+				REVERSE64(context->state[j], context->state[j]);
+			}
+		}
+#endif
+		memcpy(digest, context->state, SHA384_DIGEST_LENGTH);
+	}
+
+	/* Zero out state data */
+	memset(context, 0, sizeof(*context));
+}
+
+/*** SHA-224: *********************************************************/
+void
+SHA224_Init(SHA224_CTX *context)
+{
+	if (context == NULL)
+		return;
+	memcpy(context->state, sha224_initial_hash_value, SHA256_DIGEST_LENGTH);
+	memset(context->buffer, 0, SHA256_BLOCK_LENGTH);
+	context->bitcount = 0;
+}
+
+void
+SHA224_Update(SHA224_CTX *context, const uint8 *data, size_t len)
+{
+	SHA256_Update((SHA256_CTX *) context, data, len);
+}
+
+void
+SHA224_Final(uint8 digest[], SHA224_CTX *context)
+{
+	/* If no digest buffer is passed, we don't bother doing this: */
+	if (digest != NULL)
+	{
+		SHA256_Last(context);
+
+#ifndef WORDS_BIGENDIAN
+		{
+			/* Convert TO host byte order */
+			int			j;
+
+			for (j = 0; j < 8; j++)
+			{
+				REVERSE32(context->state[j], context->state[j]);
+			}
+		}
+#endif
+		memcpy(digest, context->state, SHA224_DIGEST_LENGTH);
+	}
+
+	/* Clean up state data: */
+	memset(context, 0, sizeof(*context));
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sha2.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sha2.h b/contrib/pgcrypto/sha2.h
new file mode 100644
index 0000000..df77a7a
--- /dev/null
+++ b/contrib/pgcrypto/sha2.h
@@ -0,0 +1,100 @@
+/*	contrib/pgcrypto/sha2.h */
+/*	$OpenBSD: sha2.h,v 1.2 2004/04/28 23:11:57 millert Exp $	*/
+
+/*
+ * FILE:	sha2.h
+ * AUTHOR:	Aaron D. Gifford <me...@aarongifford.com>
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $From: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
+ */
+
+#ifndef _SHA2_H
+#define _SHA2_H
+
+/* avoid conflict with OpenSSL */
+#define SHA256_Init pg_SHA256_Init
+#define SHA256_Update pg_SHA256_Update
+#define SHA256_Final pg_SHA256_Final
+#define SHA384_Init pg_SHA384_Init
+#define SHA384_Update pg_SHA384_Update
+#define SHA384_Final pg_SHA384_Final
+#define SHA512_Init pg_SHA512_Init
+#define SHA512_Update pg_SHA512_Update
+#define SHA512_Final pg_SHA512_Final
+
+/*** SHA-224/256/384/512 Various Length Definitions ***********************/
+#define SHA224_BLOCK_LENGTH		64
+#define SHA224_DIGEST_LENGTH		28
+#define SHA224_DIGEST_STRING_LENGTH (SHA224_DIGEST_LENGTH * 2 + 1)
+#define SHA256_BLOCK_LENGTH		64
+#define SHA256_DIGEST_LENGTH		32
+#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_BLOCK_LENGTH		128
+#define SHA384_DIGEST_LENGTH		48
+#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_BLOCK_LENGTH		128
+#define SHA512_DIGEST_LENGTH		64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256/384/512 Context Structures *******************************/
+typedef struct _SHA256_CTX
+{
+	uint32		state[8];
+	uint64		bitcount;
+	uint8		buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX
+{
+	uint64		state[8];
+	uint64		bitcount[2];
+	uint8		buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+typedef SHA256_CTX SHA224_CTX;
+typedef SHA512_CTX SHA384_CTX;
+
+void		SHA224_Init(SHA224_CTX *);
+void		SHA224_Update(SHA224_CTX *, const uint8 *, size_t);
+void		SHA224_Final(uint8[SHA224_DIGEST_LENGTH], SHA224_CTX *);
+
+void		SHA256_Init(SHA256_CTX *);
+void		SHA256_Update(SHA256_CTX *, const uint8 *, size_t);
+void		SHA256_Final(uint8[SHA256_DIGEST_LENGTH], SHA256_CTX *);
+
+void		SHA384_Init(SHA384_CTX *);
+void		SHA384_Update(SHA384_CTX *, const uint8 *, size_t);
+void		SHA384_Final(uint8[SHA384_DIGEST_LENGTH], SHA384_CTX *);
+
+void		SHA512_Init(SHA512_CTX *);
+void		SHA512_Update(SHA512_CTX *, const uint8 *, size_t);
+void		SHA512_Final(uint8[SHA512_DIGEST_LENGTH], SHA512_CTX *);
+
+#endif   /* _SHA2_H */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/3des.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/3des.sql b/contrib/pgcrypto/sql/3des.sql
new file mode 100644
index 0000000..ef54592
--- /dev/null
+++ b/contrib/pgcrypto/sql/3des.sql
@@ -0,0 +1,31 @@
+--
+-- 3DES cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+-- test vector from somewhere
+SELECT encode(encrypt(
+decode('80 00 00 00 00 00 00 00', 'hex'),
+decode('01 01 01 01 01 01 01 01
+	01 01 01 01 01 01 01 01
+	01 01 01 01 01 01 01 01', 'hex'),
+'3des-ecb/pad:none'), 'hex');
+-- val 95 F8 A5 E5 DD 31 D9 00
+
+select encode(	encrypt('', 'foo', '3des'), 'hex');
+-- 10 bytes key
+select encode(	encrypt('foo', '0123456789', '3des'), 'hex');
+-- 22 bytes key
+select encode(	encrypt('foo', '0123456789012345678901', '3des'), 'hex');
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', '3des'), '0123456', '3des');
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', '3des'), 'hex');
+select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', '3des');
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789012345678901', '3des'), 'hex');
+select decrypt(encrypt('Lets try a longer message.', '0123456789012345678901', '3des'), '0123456789012345678901', '3des');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/blowfish.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/blowfish.sql b/contrib/pgcrypto/sql/blowfish.sql
new file mode 100644
index 0000000..ba8df41
--- /dev/null
+++ b/contrib/pgcrypto/sql/blowfish.sql
@@ -0,0 +1,92 @@
+--
+-- Blowfish cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+-- some standard Blowfish testvalues
+SELECT encode(encrypt(
+decode('0000000000000000', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('ffffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('1000000000000001', 'hex'),
+decode('3000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('1111111111111111', 'hex'),
+decode('1111111111111111', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('0123456789abcdef', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('01a1d6d039776742', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+-- setkey
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+
+-- with padding
+SELECT encode(encrypt(
+decode('01234567890123456789', 'hex'),
+decode('33443344334433443344334433443344', 'hex'),
+'bf-ecb'), 'hex');
+
+-- cbc
+
+-- 28 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f7220', 'hex'),
+'bf-cbc'), 'hex');
+
+-- 29 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f722000', 'hex'),
+'bf-cbc'), 'hex');
+
+-- blowfish-448
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455667704689104c2fd3b2f584023641aba61761f1f1f1f0e0e0e0effffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+-- result: c04504012e4e1f53
+
+-- empty data
+select encode(encrypt('', 'foo', 'bf'), 'hex');
+-- 10 bytes key
+select encode(encrypt('foo', '0123456789', 'bf'), 'hex');
+-- 22 bytes key
+select encode(encrypt('foo', '0123456789012345678901', 'bf'), 'hex');
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'bf'), '0123456', 'bf');
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'bf'), 'hex');
+select decrypt_iv(decode('95c7e89322525d59', 'hex'), '0123456', 'abcd', 'bf');
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'bf'), 'hex');
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'bf'), '0123456789', 'bf');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/cast5.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/cast5.sql b/contrib/pgcrypto/sql/cast5.sql
new file mode 100644
index 0000000..527a76a
--- /dev/null
+++ b/contrib/pgcrypto/sql/cast5.sql
@@ -0,0 +1,47 @@
+--
+-- Cast5 cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+-- test vectors from RFC2144
+
+-- 128 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+-- result: 23 8B 4F E5 84 7E 44 B2
+
+-- 80 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+-- result: EB 6A 71 1A 2C 02 27 1B
+
+-- 40 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+-- result: 7A C8 16 D1 6E 9B 30 2E
+
+-- cbc
+
+-- empty data
+select encode(	encrypt('', 'foo', 'cast5'), 'hex');
+-- 10 bytes key
+select encode(	encrypt('foo', '0123456789', 'cast5'), 'hex');
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'cast5'), '0123456', 'cast5');
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'cast5'), 'hex');
+select decrypt_iv(decode('384a970695ce016a', 'hex'),
+                '0123456', 'abcd', 'cast5');
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'cast5'), 'hex');
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'cast5'), '0123456789', 'cast5');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/crypt-blowfish.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/crypt-blowfish.sql b/contrib/pgcrypto/sql/crypt-blowfish.sql
new file mode 100644
index 0000000..60c1140
--- /dev/null
+++ b/contrib/pgcrypto/sql/crypt-blowfish.sql
@@ -0,0 +1,17 @@
+--
+-- crypt() and gen_salt(): bcrypt
+--
+
+SELECT crypt('', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O');
+
+SELECT crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O');
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+
+UPDATE ctest SET salt = gen_salt('bf', 8);
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/crypt-des.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/crypt-des.sql b/contrib/pgcrypto/sql/crypt-des.sql
new file mode 100644
index 0000000..fabdc65
--- /dev/null
+++ b/contrib/pgcrypto/sql/crypt-des.sql
@@ -0,0 +1,17 @@
+--
+-- crypt() and gen_salt(): crypt-des
+--
+
+SELECT crypt('', 'NB');
+
+SELECT crypt('foox', 'NB');
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+
+UPDATE ctest SET salt = gen_salt('des');
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/crypt-md5.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/crypt-md5.sql b/contrib/pgcrypto/sql/crypt-md5.sql
new file mode 100644
index 0000000..ba7befb
--- /dev/null
+++ b/contrib/pgcrypto/sql/crypt-md5.sql
@@ -0,0 +1,17 @@
+--
+-- crypt() and gen_salt(): md5
+--
+
+SELECT crypt('', '$1$Szzz0yzz');
+
+SELECT crypt('foox', '$1$Szzz0yzz');
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+
+UPDATE ctest SET salt = gen_salt('md5');
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/crypt-xdes.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/crypt-xdes.sql b/contrib/pgcrypto/sql/crypt-xdes.sql
new file mode 100644
index 0000000..d4a74f7
--- /dev/null
+++ b/contrib/pgcrypto/sql/crypt-xdes.sql
@@ -0,0 +1,17 @@
+--
+-- crypt() and gen_salt(): extended des
+--
+
+SELECT crypt('', '_J9..j2zz');
+
+SELECT crypt('foox', '_J9..j2zz');
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+
+UPDATE ctest SET salt = gen_salt('xdes', 1001);
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/des.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/des.sql b/contrib/pgcrypto/sql/des.sql
new file mode 100644
index 0000000..6abc5b5
--- /dev/null
+++ b/contrib/pgcrypto/sql/des.sql
@@ -0,0 +1,29 @@
+--
+-- DES cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+-- no official test vectors atm
+
+-- from blowfish.sql
+SELECT encode(encrypt(
+decode('0123456789abcdef', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'des-ecb/pad:none'), 'hex');
+
+-- empty data
+select encode(	encrypt('', 'foo', 'des'), 'hex');
+-- 8 bytes key
+select encode(	encrypt('foo', '01234589', 'des'), 'hex');
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'des'), '0123456', 'des');
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'des'), 'hex');
+select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des');
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '01234567', 'des'), 'hex');
+select decrypt(encrypt('Lets try a longer message.', '01234567', 'des'), '01234567', 'des');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/hmac-md5.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/hmac-md5.sql b/contrib/pgcrypto/sql/hmac-md5.sql
new file mode 100644
index 0000000..71dcd08
--- /dev/null
+++ b/contrib/pgcrypto/sql/hmac-md5.sql
@@ -0,0 +1,44 @@
+--
+-- HMAC-MD5
+--
+
+SELECT encode(hmac(
+'Hi There',
+decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
+'md5'), 'hex');
+
+-- 2
+SELECT encode(hmac(
+'Jefe',
+'what do ya want for nothing?',
+'md5'), 'hex');
+
+-- 3
+SELECT encode(hmac(
+decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'),
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'md5'), 'hex');
+
+-- 4
+SELECT encode(hmac(
+decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'),
+decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'),
+'md5'), 'hex');
+
+-- 5
+SELECT encode(hmac(
+'Test With Truncation',
+decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
+'md5'), 'hex');
+
+-- 6
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key - Hash Key First',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'md5'), 'hex');
+
+-- 7
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'md5'), 'hex');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/hmac-sha1.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/hmac-sha1.sql b/contrib/pgcrypto/sql/hmac-sha1.sql
new file mode 100644
index 0000000..6f74193
--- /dev/null
+++ b/contrib/pgcrypto/sql/hmac-sha1.sql
@@ -0,0 +1,44 @@
+--
+-- HMAC-MD5
+--
+
+SELECT encode(hmac(
+'Hi There',
+decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
+'sha1'), 'hex');
+
+-- 2
+SELECT encode(hmac(
+'Jefe',
+'what do ya want for nothing?',
+'sha1'), 'hex');
+
+-- 3
+SELECT encode(hmac(
+decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'),
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'sha1'), 'hex');
+
+-- 4
+SELECT encode(hmac(
+decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'),
+decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'),
+'sha1'), 'hex');
+
+-- 5
+SELECT encode(hmac(
+'Test With Truncation',
+decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
+'sha1'), 'hex');
+
+-- 6
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key - Hash Key First',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'sha1'), 'hex');
+
+-- 7
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'sha1'), 'hex');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/init.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/init.sql b/contrib/pgcrypto/sql/init.sql
new file mode 100644
index 0000000..5c3d100
--- /dev/null
+++ b/contrib/pgcrypto/sql/init.sql
@@ -0,0 +1,18 @@
+--
+-- init pgcrypto
+--
+
+CREATE EXTENSION pgcrypto;
+
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+-- check for encoding fn's
+SELECT encode('foo', 'hex');
+SELECT decode('666f6f', 'hex');
+
+-- check error handling
+select gen_salt('foo');
+select digest('foo', 'foo');
+select hmac('foo', 'foo', 'foo');
+select encrypt('foo', 'foo', 'foo');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/md5.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/md5.sql b/contrib/pgcrypto/sql/md5.sql
new file mode 100644
index 0000000..4df910f
--- /dev/null
+++ b/contrib/pgcrypto/sql/md5.sql
@@ -0,0 +1,11 @@
+--
+-- MD5 message digest
+--
+
+SELECT encode(digest('', 'md5'), 'hex');
+SELECT encode(digest('a', 'md5'), 'hex');
+SELECT encode(digest('abc', 'md5'), 'hex');
+SELECT encode(digest('message digest', 'md5'), 'hex');
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyz', 'md5'), 'hex');
+SELECT encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'md5'), 'hex');
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'md5'), 'hex');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-armor.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-armor.sql b/contrib/pgcrypto/sql/pgp-armor.sql
new file mode 100644
index 0000000..71ffba2
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-armor.sql
@@ -0,0 +1,58 @@
+--
+-- PGP Armor
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+select armor('');
+select armor('test');
+select dearmor(armor(''));
+select dearmor(armor('zooka'));
+
+select armor('0123456789abcdef0123456789abcdef0123456789abcdef
+0123456789abcdef0123456789abcdef0123456789abcdef');
+
+-- lots formatting
+select dearmor(' a pgp msg:
+
+-----BEGIN PGP MESSAGE-----
+Comment: Some junk
+
+em9va2E=
+
+  =D5cR
+
+-----END PGP MESSAGE-----');
+
+-- lots messages
+select dearmor('
+wrong packet:
+  -----BEGIN PGP MESSAGE-----
+
+  d3Jvbmc=
+  =vCYP
+  -----END PGP MESSAGE-----
+
+right packet:
+-----BEGIN PGP MESSAGE-----
+
+cmlnaHQ=
+=nbpj
+-----END PGP MESSAGE-----
+
+use only first packet
+-----BEGIN PGP MESSAGE-----
+
+d3Jvbmc=
+=vCYP
+-----END PGP MESSAGE-----
+');
+
+-- bad crc
+select dearmor('
+-----BEGIN PGP MESSAGE-----
+
+em9va2E=
+=ZZZZ
+-----END PGP MESSAGE-----
+');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-compression.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-compression.sql b/contrib/pgcrypto/sql/pgp-compression.sql
new file mode 100644
index 0000000..ca9ee1f
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-compression.sql
@@ -0,0 +1,30 @@
+--
+-- PGP compression support
+--
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+
+ww0ECQMCsci6AdHnELlh0kQB4jFcVwHMJg0Bulop7m3Mi36s15TAhBo0AnzIrRFrdLVCkKohsS6+
+DMcmR53SXfLoDJOv/M8uKj3QSq7oWNIp95pxfA==
+=tbSn
+-----END PGP MESSAGE-----
+'), 'key', 'expect-compress-algo=1');
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=0'),
+	'key', 'expect-compress-algo=0');
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=1'),
+	'key', 'expect-compress-algo=1');
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=2'),
+	'key', 'expect-compress-algo=2');
+
+-- level=0 should turn compression off
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key',
+			'compress-algo=2, compress-level=0'),
+	'key', 'expect-compress-algo=0');

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-decrypt.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-decrypt.sql b/contrib/pgcrypto/sql/pgp-decrypt.sql
new file mode 100644
index 0000000..93535ab
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-decrypt.sql
@@ -0,0 +1,266 @@
+--
+-- pgp_descrypt tests
+--
+
+--  Checking ciphers
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.blowfish.sha1.mdc.s2k3.z0
+
+jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS
+yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE=
+=JcP+
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCci97v0Q6Z0Zg0kQBsVf5Oe3iC+FBzUmuMV9KxmAyOMyjCc/5i8f1Eest
+UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA==
+=XtrP
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k3.z0
+
+jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI
+5FPTqAhIB2/2fjY8QEIs1ai00qphjX2NitxV/3Wn+6dufB4Q4g==
+=rCZt
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k3.z0
+
+jA0ECQMC4f/5djqCC1Rg0kQBTHEPsD+Sw7biBsM2er3vKyGPAQkuTBGKC5ie7hT/
+lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog==
+=fB6S
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+-- Checking MDC modes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.nomdc.s2k3.z0
+
+jA0EBwMCnv07rlXqWctgyS2Dm2JfOKCRL4sLSLJUC8RS2cH7cIhKSuLitOtyquB+
+u9YkgfJfsuRJmgQ9tmo=
+=60ui
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE
+8Ex1Dsdt5UPvOz8W8VKQRS6loOfOe+yyXil8W3IYFwUpdDUi+Q==
+=moGf
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+-- Checking hashes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.md5.mdc.s2k3.z0
+
+jA0EBwMClrXXtOXetohg0kQBn0Kl1ymevQZRHkdoYRHgzCwSQEiss7zYff2UNzgO
+KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA==
+=NyLk
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m
+/PM8jhgI5vxFYfNQjLl8y3fHYIomk9YflN9K/Q13iq8A8sjeTw==
+=FxbQ
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+-- Checking S2K modes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k0.z0
+
+jAQEBwAC0kQBKTaLAKE3xzps+QIZowqRNb2eAdzBw2LxEW2YD5PgNlbhJdGg+dvw
+Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw==
+=YvkV
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k1.z0
+
+jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK
+4IaWXVKEj9R2Lr2xntWWMGZtcKtjD2lFFRXXd9dZp1ZThNDz
+=dbXm
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCEq4Su3ZqNEJg0kQB4QG5jBTKF0i04xtH+avzmLhstBNRxvV3nsmB3cwl
+z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg==
+=VJKg
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k0.z0
+
+jAQECAAC0kQBBDnQWkgsx9YFaqDfWmpsiyAJ6y2xG/sBvap1dySYEMuZ+wJTXQ9E
+Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw==
+=cg+i
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k1.z0
+
+jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9
+7h8uZ2u9uRBOv222fZodGvc6bvq/4R4hAa/6qSHtm8mdmvGt
+=aHmC
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k3.z0
+
+jA0ECAMCjFn6SRi3SONg0kQBqtSHPaD0m7rXfDAhCWU/ypAsI93GuHGRyM99cvMv
+q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw==
+=K0LS
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k0.z0
+
+jAQECQAC0kQB4L1eMbani07XF2ZYiXNK9LW3v8w41oUPl7dStmrJPQFwsdxmrDHu
+rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w==
+=RGts
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k1.z0
+
+jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO
++KVJW0qhk0An+Y2KF99/bYFl9cL5D3Tl43fC8fXGl3x3m7pR
+=SUrU
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k3.z0
+
+jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+
+4+NRzL7cMW2RLAFnJbiqXDlRHMwleeuLN1up2WIxsxtYYuaBjA==
+=XZrG
+-----END PGP MESSAGE-----
+'), 'foobar');
+
+-- Checking longer passwords
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCx6dBiuqrYNRg0kQBEo63AvA1SCslxP7ayanLf1H0/hlk2nONVhTwVEWi
+tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw==
+=XKKG
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCBDvYuS990iFg0kQBW31UK5OiCjWf5x6KJ8qNNT2HZWQCjCBZMU0XsOC6
+CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg==
+=gWDh
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54');
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCqXbFafC+ofVg0kQBejyiPqH0QMERVGfmPOjtAxvyG5KDIJPYojTgVSDt
+FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q==
+=OxOF
+-----END PGP MESSAGE-----
+'), 'x');
+
+-- Checking various data
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCGJ+SpuOysINg0kQBJfSjzsW0x4OVcAyr17O7FBvMTwIGeGcJd99oTQU8
+Xtx3kDqnhUq9Z1fS3qPbi5iNP2A9NxOBxPWz2JzxhydANlgbxg==
+=W/ik
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+-- expected: 0225e3ede6f2587b076d021a189ff60aad67e066
+
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat2.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCvdpDvidNzMxg0jUBvj8eS2+1t/9/zgemxvhtc0fvdKGGbjH7dleaTJRB
+SaV9L04ky1qECNDx3XjnoKLC+H7IOQ==
+=Fxen
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+-- expected: da39a3ee5e6b4b0d3255bfef95601890afd80709
+
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat3.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCxQvxJZ3G/HRg0lgBeYmTa7/uDAjPyFwSX4CYBgpZWVn/JS8JzILrcWF8
+gFnkUKIE0PSaYFp+Yi1VlRfUtRQ/X/LYNGa7tWZS+4VQajz2Xtz4vUeAEiYFYPXk
+73Hb8m1yRhQK
+=ivrD
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+-- expected: 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
+
+-- Checking CRLF
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: crlf mess
+
+ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
+a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
+=mBP9
+-----END PGP MESSAGE-----
+'), 'key', 'convert-crlf=0'), 'sha1'), 'hex');
+-- expected: 9353062be7720f1446d30b9e75573a4833886784
+
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: crlf mess
+
+ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
+a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
+=mBP9
+-----END PGP MESSAGE-----
+'), 'key', 'convert-crlf=1'), 'sha1'), 'hex');
+-- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-encrypt-DISABLED.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-encrypt-DISABLED.sql b/contrib/pgcrypto/sql/pgp-encrypt-DISABLED.sql
new file mode 100644
index 0000000..4122300
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-encrypt-DISABLED.sql
@@ -0,0 +1 @@
+-- no random source

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-encrypt.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-encrypt.sql b/contrib/pgcrypto/sql/pgp-encrypt.sql
new file mode 100644
index 0000000..cac37c8
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-encrypt.sql
@@ -0,0 +1,97 @@
+--
+-- PGP encrypt
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+
+select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key');
+
+-- check whether the defaults are ok
+select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
+ 	'key', 'expect-cipher-algo=aes128,
+		expect-disable-mdc=0,
+		expect-sess-key=0,
+		expect-s2k-mode=3,
+		expect-s2k-digest-algo=sha1,
+		expect-compress-algo=0
+		');
+
+-- maybe the expect- stuff simply does not work
+select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
+ 	'key', 'expect-cipher-algo=bf,
+		expect-disable-mdc=1,
+		expect-sess-key=1,
+		expect-s2k-mode=0,
+		expect-s2k-digest-algo=md5,
+		expect-compress-algo=1
+		');
+
+-- bytea as text
+select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
+
+-- text as bytea
+select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
+
+
+-- algorithm change
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'),
+ 	'key', 'expect-cipher-algo=bf');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'),
+ 	'key', 'expect-cipher-algo=aes128');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'),
+ 	'key', 'expect-cipher-algo=aes192');
+
+-- s2k change
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'),
+ 	'key', 'expect-s2k-mode=0');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'),
+ 	'key', 'expect-s2k-mode=1');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'),
+ 	'key', 'expect-s2k-mode=3');
+
+-- s2k digest change
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
+ 	'key', 'expect-s2k-digest-algo=md5');
+select pgp_sym_decrypt(
+		pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'),
+ 	'key', 'expect-s2k-digest-algo=sha1');
+
+-- sess key
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'),
+ 	'key', 'expect-sess-key=0');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'),
+ 	'key', 'expect-sess-key=1');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'),
+ 	'key', 'expect-sess-key=1, expect-cipher-algo=bf');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'),
+ 	'key', 'expect-sess-key=1, expect-cipher-algo=aes192');
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'),
+ 	'key', 'expect-sess-key=1, expect-cipher-algo=aes256');
+
+-- no mdc
+select pgp_sym_decrypt(
+		pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'),
+ 	'key', 'expect-disable-mdc=1');
+
+-- crlf
+select encode(pgp_sym_decrypt_bytea(
+	pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'),
+ 	'key'), 'hex');
+
+-- conversion should be lossless
+select encode(digest(pgp_sym_decrypt(
+  pgp_sym_encrypt(E'\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'),
+ 	'key', 'convert-crlf=1'), 'sha1'), 'hex') as result,
+  encode(digest(E'\r\n0\n1\r\r\n\n2\r', 'sha1'), 'hex') as expect;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-info.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-info.sql b/contrib/pgcrypto/sql/pgp-info.sql
new file mode 100644
index 0000000..8e1d72a
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-info.sql
@@ -0,0 +1,22 @@
+--
+-- PGP info functions
+--
+
+-- pgp_key_id
+
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=1;
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=2;
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=3;
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=6;
+
+select pgp_key_id(dearmor(seckey)) from keytbl where id=1;
+select pgp_key_id(dearmor(seckey)) from keytbl where id=2;
+select pgp_key_id(dearmor(seckey)) from keytbl where id=3;
+select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
+select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
+select pgp_key_id(dearmor(seckey)) from keytbl where id=6;
+
+select pgp_key_id(dearmor(data)) as data_key_id
+from encdata order by id;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sql/pgp-pubkey-DISABLED.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sql/pgp-pubkey-DISABLED.sql b/contrib/pgcrypto/sql/pgp-pubkey-DISABLED.sql
new file mode 100644
index 0000000..d35c097
--- /dev/null
+++ b/contrib/pgcrypto/sql/pgp-pubkey-DISABLED.sql
@@ -0,0 +1 @@
+-- no bignum support


[11/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto.patch
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto.patch b/contrib/pgcrypto.patch
deleted file mode 100644
index 9663fab..0000000
--- a/contrib/pgcrypto.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile
-index dadec95..cfae9c9 100644
---- a/contrib/pgcrypto/Makefile
-+++ b/contrib/pgcrypto/Makefile
-@@ -26,7 +26,9 @@ MODULE_big	= pgcrypto
- OBJS		= $(SRCS:.c=.o)
- 
- EXTENSION = pgcrypto
--DATA = pgcrypto--1.0.sql pgcrypto--unpackaged--1.0.sql
-+DATA_built  = pgcrypto.sql
-+#DATA = pgcrypto--1.0.sql pgcrypto--unpackaged--1.0.sql
-+DATA = uninstall_pgcrypto.sql
- 
- REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
- 	$(CF_TESTS) \
-@@ -41,8 +43,8 @@ PG_CONFIG = pg_config
- PGXS := $(shell $(PG_CONFIG) --pgxs)
- include $(PGXS)
- else
--subdir = contrib/pgcrypto
--top_builddir = ../..
-+subdir = depends/thirdparty/postgresql/contrib/pgcrypto
-+top_builddir = ../../../../..
- include $(top_builddir)/src/Makefile.global
- include $(top_srcdir)/contrib/contrib-global.mk
- endif
-diff --git a/contrib/pgcrypto/pgcrypto.sql.in b/contrib/pgcrypto/pgcrypto.sql.in
-new file mode 100644
-index 0000000..8388e86
---- /dev/null
-+++ b/contrib/pgcrypto/pgcrypto.sql.in
-@@ -0,0 +1,203 @@
-+/* $PostgreSQL: pgsql/contrib/pgcrypto/pgcrypto.sql.in,v 1.15 2007/11/13 04:24:28 momjian Exp $ */
-+
-+-- Adjust this setting to control where the objects get created.
-+SET search_path = public;
-+
-+CREATE OR REPLACE FUNCTION digest(text, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_digest'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION digest(bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_digest'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION hmac(text, text, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_hmac'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION hmac(bytea, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_hmac'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION crypt(text, text)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pg_crypt'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION gen_salt(text)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pg_gen_salt'
-+LANGUAGE C VOLATILE STRICT;
-+
-+CREATE OR REPLACE FUNCTION gen_salt(text, int4)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pg_gen_salt_rounds'
-+LANGUAGE C VOLATILE STRICT;
-+
-+CREATE OR REPLACE FUNCTION encrypt(bytea, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_encrypt'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION decrypt(bytea, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_decrypt'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION encrypt_iv(bytea, bytea, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_encrypt_iv'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION decrypt_iv(bytea, bytea, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_decrypt_iv'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION gen_random_bytes(int4)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_random_bytes'
-+LANGUAGE 'C' VOLATILE STRICT;
-+
-+--
-+-- pgp_sym_encrypt(data, key)
-+--
-+CREATE OR REPLACE FUNCTION pgp_sym_encrypt(text, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
-+LANGUAGE C STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_sym_encrypt_bytea(bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
-+LANGUAGE C STRICT;
-+
-+--
-+-- pgp_sym_encrypt(data, key, args)
-+--
-+CREATE OR REPLACE FUNCTION pgp_sym_encrypt(text, text, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
-+LANGUAGE C STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_sym_encrypt_bytea(bytea, text, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
-+LANGUAGE C STRICT;
-+
-+--
-+-- pgp_sym_decrypt(data, key)
-+--
-+CREATE OR REPLACE FUNCTION pgp_sym_decrypt(bytea, text)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_sym_decrypt_bytea(bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+--
-+-- pgp_sym_decrypt(data, key, args)
-+--
-+CREATE OR REPLACE FUNCTION pgp_sym_decrypt(bytea, text, text)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_sym_decrypt_bytea(bytea, text, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+--
-+-- pgp_pub_encrypt(data, key)
-+--
-+CREATE OR REPLACE FUNCTION pgp_pub_encrypt(text, bytea)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
-+LANGUAGE C STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
-+LANGUAGE C STRICT;
-+
-+--
-+-- pgp_pub_encrypt(data, key, args)
-+--
-+CREATE OR REPLACE FUNCTION pgp_pub_encrypt(text, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
-+LANGUAGE C STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
-+LANGUAGE C STRICT;
-+
-+--
-+-- pgp_pub_decrypt(data, key)
-+--
-+CREATE OR REPLACE FUNCTION pgp_pub_decrypt(bytea, bytea)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+--
-+-- pgp_pub_decrypt(data, key, psw)
-+--
-+CREATE OR REPLACE FUNCTION pgp_pub_decrypt(bytea, bytea, text)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+--
-+-- pgp_pub_decrypt(data, key, psw, arg)
-+--
-+CREATE OR REPLACE FUNCTION pgp_pub_decrypt(bytea, bytea, text, text)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+--
-+-- PGP key ID
-+--
-+CREATE OR REPLACE FUNCTION pgp_key_id(bytea)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pgp_key_id_w'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+--
-+-- pgp armor
-+--
-+CREATE OR REPLACE FUNCTION armor(bytea)
-+RETURNS text
-+AS 'MODULE_PATHNAME', 'pg_armor'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-+CREATE OR REPLACE FUNCTION dearmor(text)
-+RETURNS bytea
-+AS 'MODULE_PATHNAME', 'pg_dearmor'
-+LANGUAGE C IMMUTABLE STRICT;
-+
-diff --git a/contrib/pgcrypto/uninstall_pgcrypto.sql b/contrib/pgcrypto/uninstall_pgcrypto.sql
-new file mode 100644
-index 0000000..a2891f6
---- /dev/null
-+++ b/contrib/pgcrypto/uninstall_pgcrypto.sql
-@@ -0,0 +1,46 @@
-+/* $PostgreSQL: pgsql/contrib/pgcrypto/uninstall_pgcrypto.sql,v 1.4 2007/11/13 04:24:28 momjian Exp $ */
-+
-+-- Adjust this setting to control where the objects get dropped.
-+SET search_path = public;
-+
-+DROP FUNCTION digest(text, text);
-+DROP FUNCTION digest(bytea, text);
-+
-+DROP FUNCTION hmac(text, text, text);
-+DROP FUNCTION hmac(bytea, bytea, text);
-+
-+DROP FUNCTION crypt(text, text);
-+DROP FUNCTION gen_salt(text);
-+DROP FUNCTION gen_salt(text, int4);
-+
-+DROP FUNCTION encrypt(bytea, bytea, text);
-+DROP FUNCTION decrypt(bytea, bytea, text);
-+DROP FUNCTION encrypt_iv(bytea, bytea, bytea, text);
-+DROP FUNCTION decrypt_iv(bytea, bytea, bytea, text);
-+
-+DROP FUNCTION gen_random_bytes(int4);
-+
-+DROP FUNCTION pgp_sym_encrypt(text, text);
-+DROP FUNCTION pgp_sym_encrypt_bytea(bytea, text);
-+DROP FUNCTION pgp_sym_encrypt(text, text, text);
-+DROP FUNCTION pgp_sym_encrypt_bytea(bytea, text, text);
-+DROP FUNCTION pgp_sym_decrypt(bytea, text);
-+DROP FUNCTION pgp_sym_decrypt_bytea(bytea, text);
-+DROP FUNCTION pgp_sym_decrypt(bytea, text, text);
-+DROP FUNCTION pgp_sym_decrypt_bytea(bytea, text, text);
-+
-+DROP FUNCTION pgp_pub_encrypt(text, bytea);
-+DROP FUNCTION pgp_pub_encrypt_bytea(bytea, bytea);
-+DROP FUNCTION pgp_pub_encrypt(text, bytea, text);
-+DROP FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text);
-+DROP FUNCTION pgp_pub_decrypt(bytea, bytea);
-+DROP FUNCTION pgp_pub_decrypt_bytea(bytea, bytea);
-+DROP FUNCTION pgp_pub_decrypt(bytea, bytea, text);
-+DROP FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text);
-+DROP FUNCTION pgp_pub_decrypt(bytea, bytea, text, text);
-+DROP FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text);
-+
-+DROP FUNCTION pgp_key_id(bytea);
-+DROP FUNCTION armor(bytea);
-+DROP FUNCTION dearmor(text);
-+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/.gitignore
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/.gitignore b/contrib/pgcrypto/.gitignore
new file mode 100644
index 0000000..dc533ee
--- /dev/null
+++ b/contrib/pgcrypto/.gitignore
@@ -0,0 +1,5 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
+pgcrypto.sql

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/Makefile
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile
new file mode 100644
index 0000000..b7cb3a6
--- /dev/null
+++ b/contrib/pgcrypto/Makefile
@@ -0,0 +1,66 @@
+# contrib/pgcrypto/Makefile
+
+INT_SRCS = md5.c sha1.c sha2.c internal.c internal-sha2.c blf.c rijndael.c \
+		fortuna.c random.c pgp-mpi-internal.c imath.c
+INT_TESTS = sha2
+
+OSSL_SRCS = openssl.c pgp-mpi-openssl.c
+OSSL_TESTS = sha2 des 3des cast5
+
+ZLIB_TST = pgp-compression
+ZLIB_OFF_TST = pgp-zlib-DISABLED
+
+CF_SRCS = $(if $(subst no,,$(with_openssl)), $(OSSL_SRCS), $(INT_SRCS))
+CF_TESTS = $(if $(subst no,,$(with_openssl)), $(OSSL_TESTS), $(INT_TESTS))
+CF_PGP_TESTS = $(if $(subst no,,$(with_zlib)), $(ZLIB_TST), $(ZLIB_OFF_TST))
+
+SRCS		= pgcrypto.c px.c px-hmac.c px-crypt.c \
+		crypt-gensalt.c crypt-blowfish.c crypt-des.c \
+		crypt-md5.c $(CF_SRCS) \
+		mbuf.c pgp.c pgp-armor.c pgp-cfb.c pgp-compress.c \
+		pgp-decrypt.c pgp-encrypt.c pgp-info.c pgp-mpi.c \
+		pgp-pubdec.c pgp-pubenc.c pgp-pubkey.c pgp-s2k.c \
+		pgp-pgsql.c
+
+MODULE_big	= pgcrypto
+OBJS		= $(SRCS:.c=.o)
+
+EXTENSION = pgcrypto
+DATA_built  = pgcrypto.sql
+#DATA = pgcrypto--1.0.sql pgcrypto--unpackaged--1.0.sql
+DATA = uninstall_pgcrypto.sql
+
+REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
+	$(CF_TESTS) \
+	crypt-des crypt-md5 crypt-blowfish crypt-xdes \
+	pgp-armor pgp-decrypt pgp-encrypt $(CF_PGP_TESTS) \
+	pgp-pubkey-decrypt pgp-pubkey-encrypt pgp-info
+
+EXTRA_CLEAN = gen-rtab
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = contrib/pgcrypto
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
+
+# Add libraries that pgcrypto depends (or might depend) on into the
+# shared library link.  (The order in which you list them here doesn't
+# matter.)
+SHLIB_LINK += $(filter -lcrypto -lz, $(LIBS))
+ifeq ($(PORTNAME), win32)
+SHLIB_LINK += $(filter -leay32, $(LIBS))
+# those must be at the end
+SHLIB_LINK += -lwsock32 -lws2_32
+endif
+
+rijndael.o: rijndael.tbl
+
+rijndael.tbl:
+	$(CC) $(CPPFLAGS) $(CFLAGS) -DPRINT_TABS rijndael.c -o gen-rtab
+	./gen-rtab > rijndael.tbl

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/blf.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/blf.c b/contrib/pgcrypto/blf.c
new file mode 100644
index 0000000..f8a2c63
--- /dev/null
+++ b/contrib/pgcrypto/blf.c
@@ -0,0 +1,499 @@
+/*
+ * Butchered version of sshblowf.c from putty-0.59.
+ *
+ * contrib/pgcrypto/blf.c
+ */
+
+/*
+ * PuTTY is copyright 1997-2007 Simon Tatham.
+ *
+ * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+ * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+ * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
+ * Kuhn, and CORE SDI S.A.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Blowfish implementation for PuTTY.
+ *
+ * Coded from scratch from the algorithm description.
+ */
+
+#include "postgres.h"
+#include "blf.h"
+
+#define GET_32BIT_MSB_FIRST(p) ( \
+	((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3]) )
+
+#define PUT_32BIT_MSB_FIRST(p, v) do { \
+	(p)[0] = v >> 24; \
+	(p)[1] = v >> 16; \
+	(p)[2] = v >> 8; \
+	(p)[3] = v; \
+} while (0)
+
+/*
+ * The Blowfish init data: hex digits of the fractional part of pi.
+ * (ie pi as a hex fraction is 3.243F6A8885A308D3...)
+ */
+static const uint32 parray[] = {
+	0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
+	0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
+	0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B,
+};
+
+static const uint32 sbox0[] = {
+	0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
+	0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
+	0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
+	0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
+	0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
+	0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
+	0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6,
+	0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
+	0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
+	0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
+	0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1,
+	0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
+	0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
+	0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
+	0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
+	0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
+	0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
+	0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
+	0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B,
+	0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
+	0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
+	0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
+	0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A,
+	0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
+	0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760,
+	0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
+	0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
+	0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
+	0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33,
+	0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
+	0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0,
+	0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
+	0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
+	0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
+	0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705,
+	0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
+	0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E,
+	0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
+	0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
+	0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
+	0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F,
+	0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
+	0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A,
+};
+
+static const uint32 sbox1[] = {
+	0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
+	0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
+	0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
+	0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
+	0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
+	0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
+	0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D,
+	0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
+	0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
+	0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
+	0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908,
+	0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
+	0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124,
+	0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
+	0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
+	0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
+	0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B,
+	0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
+	0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA,
+	0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
+	0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
+	0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
+	0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5,
+	0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
+	0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96,
+	0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
+	0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
+	0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
+	0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77,
+	0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
+	0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054,
+	0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
+	0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
+	0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
+	0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646,
+	0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
+	0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA,
+	0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
+	0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
+	0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
+	0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD,
+	0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
+	0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7,
+};
+
+static const uint32 sbox2[] = {
+	0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7,
+	0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
+	0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
+	0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
+	0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4,
+	0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
+	0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC,
+	0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
+	0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
+	0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
+	0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58,
+	0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
+	0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22,
+	0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
+	0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
+	0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
+	0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99,
+	0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
+	0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74,
+	0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
+	0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
+	0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
+	0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979,
+	0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
+	0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA,
+	0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
+	0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
+	0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
+	0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24,
+	0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
+	0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84,
+	0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
+	0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
+	0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
+	0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE,
+	0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
+	0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0,
+	0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
+	0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
+	0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
+	0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8,
+	0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
+	0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0,
+};
+
+static const uint32 sbox3[] = {
+	0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742,
+	0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
+	0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
+	0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
+	0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A,
+	0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
+	0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1,
+	0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
+	0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
+	0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
+	0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6,
+	0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
+	0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA,
+	0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
+	0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
+	0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
+	0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE,
+	0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
+	0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD,
+	0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
+	0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
+	0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
+	0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC,
+	0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
+	0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC,
+	0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
+	0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
+	0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
+	0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A,
+	0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
+	0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B,
+	0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
+	0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
+	0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
+	0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623,
+	0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
+	0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A,
+	0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
+	0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
+	0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
+	0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C,
+	0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
+	0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6,
+};
+
+#define Fprime(a,b,c,d) ( ( (S0[a] + S1[b]) ^ S2[c] ) + S3[d] )
+#define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) )
+#define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t )
+
+static void
+blowfish_encrypt(uint32 xL, uint32 xR, uint32 *output,
+				 BlowfishContext *ctx)
+{
+	uint32	   *S0 = ctx->S0;
+	uint32	   *S1 = ctx->S1;
+	uint32	   *S2 = ctx->S2;
+	uint32	   *S3 = ctx->S3;
+	uint32	   *P = ctx->P;
+	uint32		t;
+
+	ROUND(0);
+	ROUND(1);
+	ROUND(2);
+	ROUND(3);
+	ROUND(4);
+	ROUND(5);
+	ROUND(6);
+	ROUND(7);
+	ROUND(8);
+	ROUND(9);
+	ROUND(10);
+	ROUND(11);
+	ROUND(12);
+	ROUND(13);
+	ROUND(14);
+	ROUND(15);
+	xL ^= P[16];
+	xR ^= P[17];
+
+	output[0] = xR;
+	output[1] = xL;
+}
+
+static void
+blowfish_decrypt(uint32 xL, uint32 xR, uint32 *output,
+				 BlowfishContext *ctx)
+{
+	uint32	   *S0 = ctx->S0;
+	uint32	   *S1 = ctx->S1;
+	uint32	   *S2 = ctx->S2;
+	uint32	   *S3 = ctx->S3;
+	uint32	   *P = ctx->P;
+	uint32		t;
+
+	ROUND(17);
+	ROUND(16);
+	ROUND(15);
+	ROUND(14);
+	ROUND(13);
+	ROUND(12);
+	ROUND(11);
+	ROUND(10);
+	ROUND(9);
+	ROUND(8);
+	ROUND(7);
+	ROUND(6);
+	ROUND(5);
+	ROUND(4);
+	ROUND(3);
+	ROUND(2);
+	xL ^= P[1];
+	xR ^= P[0];
+
+	output[0] = xR;
+	output[1] = xL;
+}
+
+void
+blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2],
+				iv0,
+				iv1;
+
+	Assert((len & 7) == 0);
+
+	iv0 = ctx->iv0;
+	iv1 = ctx->iv1;
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		iv0 ^= xL;
+		iv1 ^= xR;
+		blowfish_encrypt(iv0, iv1, out, ctx);
+		iv0 = out[0];
+		iv1 = out[1];
+		PUT_32BIT_MSB_FIRST(blk, iv0);
+		PUT_32BIT_MSB_FIRST(blk + 4, iv1);
+		blk += 8;
+		len -= 8;
+	}
+
+	ctx->iv0 = iv0;
+	ctx->iv1 = iv1;
+}
+
+void
+blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2],
+				iv0,
+				iv1;
+
+	Assert((len & 7) == 0);
+
+	iv0 = ctx->iv0;
+	iv1 = ctx->iv1;
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		blowfish_decrypt(xL, xR, out, ctx);
+		iv0 ^= out[0];
+		iv1 ^= out[1];
+		PUT_32BIT_MSB_FIRST(blk, iv0);
+		PUT_32BIT_MSB_FIRST(blk + 4, iv1);
+		iv0 = xL;
+		iv1 = xR;
+		blk += 8;
+		len -= 8;
+	}
+
+	ctx->iv0 = iv0;
+	ctx->iv1 = iv1;
+}
+
+void
+blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2];
+
+	Assert((len & 7) == 0);
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		blowfish_encrypt(xL, xR, out, ctx);
+		PUT_32BIT_MSB_FIRST(blk, out[0]);
+		PUT_32BIT_MSB_FIRST(blk + 4, out[1]);
+		blk += 8;
+		len -= 8;
+	}
+}
+
+void
+blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2];
+
+	Assert((len & 7) == 0);
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		blowfish_decrypt(xL, xR, out, ctx);
+		PUT_32BIT_MSB_FIRST(blk, out[0]);
+		PUT_32BIT_MSB_FIRST(blk + 4, out[1]);
+		blk += 8;
+		len -= 8;
+	}
+}
+
+void
+blowfish_setkey(BlowfishContext *ctx,
+				const uint8 *key, short keybytes)
+{
+	uint32	   *S0 = ctx->S0;
+	uint32	   *S1 = ctx->S1;
+	uint32	   *S2 = ctx->S2;
+	uint32	   *S3 = ctx->S3;
+	uint32	   *P = ctx->P;
+	uint32		str[2];
+	int			i;
+
+	Assert(keybytes > 0 && keybytes <= (448 / 8));
+
+	for (i = 0; i < 18; i++)
+	{
+		P[i] = parray[i];
+		P[i] ^= ((uint32) key[(i * 4 + 0) % keybytes]) << 24;
+		P[i] ^= ((uint32) key[(i * 4 + 1) % keybytes]) << 16;
+		P[i] ^= ((uint32) key[(i * 4 + 2) % keybytes]) << 8;
+		P[i] ^= ((uint32) key[(i * 4 + 3) % keybytes]);
+	}
+
+	for (i = 0; i < 256; i++)
+	{
+		S0[i] = sbox0[i];
+		S1[i] = sbox1[i];
+		S2[i] = sbox2[i];
+		S3[i] = sbox3[i];
+	}
+
+	str[0] = str[1] = 0;
+
+	for (i = 0; i < 18; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		P[i] = str[0];
+		P[i + 1] = str[1];
+	}
+
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S0[i] = str[0];
+		S0[i + 1] = str[1];
+	}
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S1[i] = str[0];
+		S1[i + 1] = str[1];
+	}
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S2[i] = str[0];
+		S2[i + 1] = str[1];
+	}
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S3[i] = str[0];
+		S3[i + 1] = str[1];
+	}
+}
+
+void
+blowfish_setiv(BlowfishContext *ctx, const uint8 *iv)
+{
+	ctx->iv0 = GET_32BIT_MSB_FIRST(iv);
+	ctx->iv1 = GET_32BIT_MSB_FIRST(iv + 4);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/blf.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/blf.h b/contrib/pgcrypto/blf.h
new file mode 100644
index 0000000..84aba37
--- /dev/null
+++ b/contrib/pgcrypto/blf.h
@@ -0,0 +1,46 @@
+/* contrib/pgcrypto/blf.h */
+/*
+ * PuTTY is copyright 1997-2007 Simon Tatham.
+ *
+ * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+ * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+ * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
+ * Kuhn, and CORE SDI S.A.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+typedef struct
+{
+	uint32		S0[256],
+				S1[256],
+				S2[256],
+				S3[256],
+				P[18];
+	uint32		iv0,
+				iv1;			/* for CBC mode */
+} BlowfishContext;
+
+void		blowfish_setkey(BlowfishContext *ctx, const uint8 *key, short keybytes);
+void		blowfish_setiv(BlowfishContext *ctx, const uint8 *iv);
+void		blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx);
+void		blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx);
+void		blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx);
+void		blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx);

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/crypt-blowfish.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/crypt-blowfish.c b/contrib/pgcrypto/crypt-blowfish.c
new file mode 100644
index 0000000..b49747d
--- /dev/null
+++ b/contrib/pgcrypto/crypt-blowfish.c
@@ -0,0 +1,735 @@
+/*
+ * contrib/pgcrypto/crypt-blowfish.c
+ *
+ * This code comes from John the Ripper password cracker, with reentrant
+ * and crypt(3) interfaces added, but optimizations specific to password
+ * cracking removed.
+ *
+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
+ * placed in the public domain.
+ *
+ * There's absolutely no warranty.
+ *
+ * It is my intent that you should be able to use this on your system,
+ * as a part of a software package, or anywhere else to improve security,
+ * ensure compatibility, or for any other purpose. I would appreciate
+ * it if you give credit where it is due and keep your modifications in
+ * the public domain as well, but I don't require that in order to let
+ * you place this code and any modifications you make under a license
+ * of your choice.
+ *
+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
+ * ideas.  The password hashing algorithm was designed by David Mazieres
+ * <dm at lcs.mit.edu>.
+ *
+ * There's a paper on the algorithm that explains its design decisions:
+ *
+ *	http://www.usenix.org/events/usenix99/provos.html
+ *
+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
+ * Blowfish library (I can't be sure if I would think of something if I
+ * hadn't seen his code).
+ */
+
+#include "postgres.h"
+
+#include "px-crypt.h"
+
+#ifdef __i386__
+#define BF_ASM				0	/* 1 */
+#define BF_SCALE			1
+#elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__)
+#define BF_ASM				0
+#define BF_SCALE			1
+#else
+#define BF_ASM				0
+#define BF_SCALE			0
+#endif
+
+typedef unsigned int BF_word;
+typedef signed int BF_word_signed;
+
+/* Number of Blowfish rounds, this is also hardcoded into a few places */
+#define BF_N				16
+
+typedef BF_word BF_key[BF_N + 2];
+
+typedef struct
+{
+	BF_word		S[4][0x100];
+	BF_key		P;
+} BF_ctx;
+
+/*
+ * Magic IV for 64 Blowfish encryptions that we do at the end.
+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
+ */
+static BF_word BF_magic_w[6] = {
+	0x4F727068, 0x65616E42, 0x65686F6C,
+	0x64657253, 0x63727944, 0x6F756274
+};
+
+/*
+ * P-box and S-box tables initialized with digits of Pi.
+ */
+static BF_ctx BF_init_state = {
+	{
+		{
+			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+			0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+		}, {
+			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+			0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+		}, {
+			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+			0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+		}, {
+			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+			0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+		}
+	}, {
+		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+		0x9216d5d9, 0x8979fb1b
+	}
+};
+
+static unsigned char BF_itoa64[64 + 1] =
+"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static unsigned char BF_atoi64[0x60] = {
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
+	54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
+	64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
+	64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+	43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
+};
+
+#define BF_safe_atoi64(dst, src) \
+do { \
+	tmp = (unsigned char)(src); \
+	if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
+	tmp = BF_atoi64[tmp]; \
+	if (tmp > 63) return -1; \
+	(dst) = tmp; \
+} while (0)
+
+static int
+BF_decode(BF_word *dst, const char *src, int size)
+{
+	unsigned char *dptr = (unsigned char *) dst;
+	unsigned char *end = dptr + size;
+	const unsigned char *sptr = (const unsigned char *) src;
+	unsigned int tmp,
+				c1,
+				c2,
+				c3,
+				c4;
+
+	do
+	{
+		BF_safe_atoi64(c1, *sptr++);
+		BF_safe_atoi64(c2, *sptr++);
+		*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
+		if (dptr >= end)
+			break;
+
+		BF_safe_atoi64(c3, *sptr++);
+		*dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
+		if (dptr >= end)
+			break;
+
+		BF_safe_atoi64(c4, *sptr++);
+		*dptr++ = ((c3 & 0x03) << 6) | c4;
+	} while (dptr < end);
+
+	return 0;
+}
+
+static void
+BF_encode(char *dst, const BF_word *src, int size)
+{
+	const unsigned char *sptr = (const unsigned char *) src;
+	const unsigned char *end = sptr + size;
+	unsigned char *dptr = (unsigned char *) dst;
+	unsigned int c1,
+				c2;
+
+	do
+	{
+		c1 = *sptr++;
+		*dptr++ = BF_itoa64[c1 >> 2];
+		c1 = (c1 & 0x03) << 4;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 4;
+		*dptr++ = BF_itoa64[c1];
+		c1 = (c2 & 0x0f) << 2;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 6;
+		*dptr++ = BF_itoa64[c1];
+		*dptr++ = BF_itoa64[c2 & 0x3f];
+	} while (sptr < end);
+}
+
+static void
+BF_swap(BF_word *x, int count)
+{
+	/* Swap on little-endian hardware, else do nothing */
+#ifndef WORDS_BIGENDIAN
+	BF_word		tmp;
+
+	do
+	{
+		tmp = *x;
+		tmp = (tmp << 16) | (tmp >> 16);
+		*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
+	} while (--count);
+#endif
+}
+
+#if BF_SCALE
+/* Architectures which can shift addresses left by 2 bits with no extra cost */
+#define BF_ROUND(L, R, N) \
+	tmp1 = (L) & 0xFF; \
+	tmp2 = (L) >> 8; \
+	tmp2 &= 0xFF; \
+	tmp3 = (L) >> 16; \
+	tmp3 &= 0xFF; \
+	tmp4 = (L) >> 24; \
+	tmp1 = data.ctx.S[3][tmp1]; \
+	tmp2 = data.ctx.S[2][tmp2]; \
+	tmp3 = data.ctx.S[1][tmp3]; \
+	tmp3 += data.ctx.S[0][tmp4]; \
+	tmp3 ^= tmp2; \
+	(R) ^= data.ctx.P[(N) + 1]; \
+	tmp3 += tmp1; \
+	(R) ^= tmp3;
+#else
+/* Architectures with no complicated addressing modes supported */
+#define BF_INDEX(S, i) \
+	(*((BF_word *)(((unsigned char *)(S)) + (i))))
+#define BF_ROUND(L, R, N) \
+	tmp1 = (L) & 0xFF; \
+	tmp1 <<= 2; \
+	tmp2 = (L) >> 6; \
+	tmp2 &= 0x3FC; \
+	tmp3 = (L) >> 14; \
+	tmp3 &= 0x3FC; \
+	tmp4 = (L) >> 22; \
+	tmp4 &= 0x3FC; \
+	tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
+	tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
+	tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
+	tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
+	tmp3 ^= tmp2; \
+	(R) ^= data.ctx.P[(N) + 1]; \
+	tmp3 += tmp1; \
+	(R) ^= tmp3;
+#endif
+
+/*
+ * Encrypt one block, BF_N is hardcoded here.
+ */
+#define BF_ENCRYPT \
+	L ^= data.ctx.P[0]; \
+	BF_ROUND(L, R, 0); \
+	BF_ROUND(R, L, 1); \
+	BF_ROUND(L, R, 2); \
+	BF_ROUND(R, L, 3); \
+	BF_ROUND(L, R, 4); \
+	BF_ROUND(R, L, 5); \
+	BF_ROUND(L, R, 6); \
+	BF_ROUND(R, L, 7); \
+	BF_ROUND(L, R, 8); \
+	BF_ROUND(R, L, 9); \
+	BF_ROUND(L, R, 10); \
+	BF_ROUND(R, L, 11); \
+	BF_ROUND(L, R, 12); \
+	BF_ROUND(R, L, 13); \
+	BF_ROUND(L, R, 14); \
+	BF_ROUND(R, L, 15); \
+	tmp4 = R; \
+	R = L; \
+	L = tmp4 ^ data.ctx.P[BF_N + 1];
+
+#if BF_ASM
+
+extern void _BF_body_r(BF_ctx *ctx);
+
+#define BF_body() \
+	_BF_body_r(&data.ctx);
+#else
+
+#define BF_body() \
+	L = R = 0; \
+	ptr = data.ctx.P; \
+	do { \
+		ptr += 2; \
+		BF_ENCRYPT; \
+		*(ptr - 2) = L; \
+		*(ptr - 1) = R; \
+	} while (ptr < &data.ctx.P[BF_N + 2]); \
+\
+	ptr = data.ctx.S[0]; \
+	do { \
+		ptr += 2; \
+		BF_ENCRYPT; \
+		*(ptr - 2) = L; \
+		*(ptr - 1) = R; \
+	} while (ptr < &data.ctx.S[3][0xFF]);
+#endif
+
+static void
+BF_set_key(const char *key, BF_key expanded, BF_key initial,
+		   int sign_extension_bug)
+{
+	const char *ptr = key;
+	int			i,
+				j;
+	BF_word		tmp;
+
+	for (i = 0; i < BF_N + 2; i++)
+	{
+		tmp = 0;
+		for (j = 0; j < 4; j++)
+		{
+			tmp <<= 8;
+			if (sign_extension_bug)
+				tmp |= (BF_word_signed) (signed char) *ptr;
+			else
+				tmp |= (unsigned char) *ptr;
+
+			if (!*ptr)
+				ptr = key;
+			else
+				ptr++;
+		}
+
+		expanded[i] = tmp;
+		initial[i] = BF_init_state.P[i] ^ tmp;
+	}
+}
+
+char *
+_crypt_blowfish_rn(const char *key, const char *setting,
+				   char *output, int size)
+{
+	struct
+	{
+		BF_ctx		ctx;
+		BF_key		expanded_key;
+		union
+		{
+			BF_word		salt[4];
+			BF_word		output[6];
+		}			binary;
+	}			data;
+	BF_word		L,
+				R;
+	BF_word		tmp1,
+				tmp2,
+				tmp3,
+				tmp4;
+	BF_word    *ptr;
+	BF_word		count;
+	int			i;
+
+	if (size < 7 + 22 + 31 + 1)
+		return NULL;
+
+	if (setting[0] != '$' ||
+		setting[1] != '2' ||
+		(setting[2] != 'a' && setting[2] != 'x') ||
+		setting[3] != '$' ||
+		setting[4] < '0' || setting[4] > '3' ||
+		setting[5] < '0' || setting[5] > '9' ||
+		(setting[4] == '3' && setting[5] > '1') ||
+		setting[6] != '$')
+	{
+		return NULL;
+	}
+
+	count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
+	if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16))
+	{
+		memset(data.binary.salt, 0, sizeof(data.binary.salt));
+		return NULL;
+	}
+	BF_swap(data.binary.salt, 4);
+
+	BF_set_key(key, data.expanded_key, data.ctx.P, setting[2] == 'x');
+
+	memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
+
+	L = R = 0;
+	for (i = 0; i < BF_N + 2; i += 2)
+	{
+		L ^= data.binary.salt[i & 2];
+		R ^= data.binary.salt[(i & 2) + 1];
+		BF_ENCRYPT;
+		data.ctx.P[i] = L;
+		data.ctx.P[i + 1] = R;
+	}
+
+	ptr = data.ctx.S[0];
+	do
+	{
+		ptr += 4;
+		L ^= data.binary.salt[(BF_N + 2) & 3];
+		R ^= data.binary.salt[(BF_N + 3) & 3];
+		BF_ENCRYPT;
+		*(ptr - 4) = L;
+		*(ptr - 3) = R;
+
+		L ^= data.binary.salt[(BF_N + 4) & 3];
+		R ^= data.binary.salt[(BF_N + 5) & 3];
+		BF_ENCRYPT;
+		*(ptr - 2) = L;
+		*(ptr - 1) = R;
+	} while (ptr < &data.ctx.S[3][0xFF]);
+
+	do
+	{
+		data.ctx.P[0] ^= data.expanded_key[0];
+		data.ctx.P[1] ^= data.expanded_key[1];
+		data.ctx.P[2] ^= data.expanded_key[2];
+		data.ctx.P[3] ^= data.expanded_key[3];
+		data.ctx.P[4] ^= data.expanded_key[4];
+		data.ctx.P[5] ^= data.expanded_key[5];
+		data.ctx.P[6] ^= data.expanded_key[6];
+		data.ctx.P[7] ^= data.expanded_key[7];
+		data.ctx.P[8] ^= data.expanded_key[8];
+		data.ctx.P[9] ^= data.expanded_key[9];
+		data.ctx.P[10] ^= data.expanded_key[10];
+		data.ctx.P[11] ^= data.expanded_key[11];
+		data.ctx.P[12] ^= data.expanded_key[12];
+		data.ctx.P[13] ^= data.expanded_key[13];
+		data.ctx.P[14] ^= data.expanded_key[14];
+		data.ctx.P[15] ^= data.expanded_key[15];
+		data.ctx.P[16] ^= data.expanded_key[16];
+		data.ctx.P[17] ^= data.expanded_key[17];
+
+		BF_body();
+
+		tmp1 = data.binary.salt[0];
+		tmp2 = data.binary.salt[1];
+		tmp3 = data.binary.salt[2];
+		tmp4 = data.binary.salt[3];
+		data.ctx.P[0] ^= tmp1;
+		data.ctx.P[1] ^= tmp2;
+		data.ctx.P[2] ^= tmp3;
+		data.ctx.P[3] ^= tmp4;
+		data.ctx.P[4] ^= tmp1;
+		data.ctx.P[5] ^= tmp2;
+		data.ctx.P[6] ^= tmp3;
+		data.ctx.P[7] ^= tmp4;
+		data.ctx.P[8] ^= tmp1;
+		data.ctx.P[9] ^= tmp2;
+		data.ctx.P[10] ^= tmp3;
+		data.ctx.P[11] ^= tmp4;
+		data.ctx.P[12] ^= tmp1;
+		data.ctx.P[13] ^= tmp2;
+		data.ctx.P[14] ^= tmp3;
+		data.ctx.P[15] ^= tmp4;
+		data.ctx.P[16] ^= tmp1;
+		data.ctx.P[17] ^= tmp2;
+
+		BF_body();
+	} while (--count);
+
+	for (i = 0; i < 6; i += 2)
+	{
+		L = BF_magic_w[i];
+		R = BF_magic_w[i + 1];
+
+		count = 64;
+		do
+		{
+			BF_ENCRYPT;
+		} while (--count);
+
+		data.binary.output[i] = L;
+		data.binary.output[i + 1] = R;
+	}
+
+	memcpy(output, setting, 7 + 22 - 1);
+	output[7 + 22 - 1] = BF_itoa64[(int)
+						 BF_atoi64[(int) setting[7 + 22 - 1] - 0x20] & 0x30];
+
+/* This has to be bug-compatible with the original implementation, so
+ * only encode 23 of the 24 bytes. :-) */
+	BF_swap(data.binary.output, 6);
+	BF_encode(&output[7 + 22], data.binary.output, 23);
+	output[7 + 22 + 31] = '\0';
+
+/* Overwrite the most obvious sensitive data we have on the stack. Note
+ * that this does not guarantee there's no sensitive data left on the
+ * stack and/or in registers; I'm not aware of portable code that does. */
+	memset(&data, 0, sizeof(data));
+
+	return output;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/crypt-des.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/crypt-des.c b/contrib/pgcrypto/crypt-des.c
new file mode 100644
index 0000000..cc2e76a
--- /dev/null
+++ b/contrib/pgcrypto/crypt-des.c
@@ -0,0 +1,774 @@
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * contrib/pgcrypto/crypt-des.c
+ *
+ * Copyright (c) 1994 David Burren
+ * All rights reserved.
+ *
+ * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
+ *	this file should now *only* export crypt(), in order to make
+ *	binaries of libcrypt exportable from the USA
+ *
+ * Adapted for FreeBSD-4.0 by Mark R V Murray
+ *	this file should now *only* export crypt_des(), in order to make
+ *	a module that can be optionally included in libcrypt.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 author nor the names of other contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/secure/lib/libcrypt/crypt-des.c,v 1.12 1999/09/20 12:39:20 markm Exp $
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren <da...@werj.com.au>.
+ *
+ * An excellent reference on the underlying algorithm (and related
+ * algorithms) is:
+ *
+ *	B. Schneier, Applied Cryptography: protocols, algorithms,
+ *	and source code in C, John Wiley & Sons, 1994.
+ *
+ * Note that in that book's description of DES the lookups for the initial,
+ * pbox, and final permutations are inverted (this has been brought to the
+ * attention of the author).  A list of errata for this book has been
+ * posted to the sci.crypt newsgroup by the author and is available for FTP.
+ *
+ * ARCHITECTURE ASSUMPTIONS:
+ *	It is assumed that the 8-byte arrays passed by reference can be
+ *	addressed as arrays of uint32's (ie. the CPU is not picky about
+ *	alignment).
+ */
+
+#include "postgres.h"
+
+#include "px-crypt.h"
+
+/* for ntohl/htonl */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define _PASSWORD_EFMT1 '_'
+
+static const char _crypt_a64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static uint8 IP[64] = {
+	58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
+	62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
+	57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
+	61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
+};
+
+static uint8 inv_key_perm[64];
+static uint8 u_key_perm[56];
+static uint8 key_perm[56] = {
+	57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
+	10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
+	63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
+	14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
+};
+
+static uint8 key_shifts[16] = {
+	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+static uint8 inv_comp_perm[56];
+static uint8 comp_perm[48] = {
+	14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
+	23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
+	41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+	44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
+};
+
+/*
+ *	No E box is used, as it's replaced by some ANDs, shifts, and ORs.
+ */
+
+static uint8 u_sbox[8][64];
+static uint8 sbox[8][64] = {
+	{
+		14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
+		0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
+		4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
+		15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
+	},
+	{
+		15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
+		3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
+		0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
+		13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
+	},
+	{
+		10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
+		13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
+		13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
+		1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
+	},
+	{
+		7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
+		13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
+		10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
+		3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
+	},
+	{
+		2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
+		14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
+		4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
+		11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
+	},
+	{
+		12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
+		10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
+		9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
+		4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
+	},
+	{
+		4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
+		13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
+		1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
+		6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
+	},
+	{
+		13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
+		1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
+		7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
+		2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
+	}
+};
+
+static uint8 un_pbox[32];
+static uint8 pbox[32] = {
+	16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
+	2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
+};
+
+static uint32 _crypt_bits32[32] =
+{
+	0x80000000, 0x40000000, 0x20000000, 0x10000000,
+	0x08000000, 0x04000000, 0x02000000, 0x01000000,
+	0x00800000, 0x00400000, 0x00200000, 0x00100000,
+	0x00080000, 0x00040000, 0x00020000, 0x00010000,
+	0x00008000, 0x00004000, 0x00002000, 0x00001000,
+	0x00000800, 0x00000400, 0x00000200, 0x00000100,
+	0x00000080, 0x00000040, 0x00000020, 0x00000010,
+	0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+static uint8 _crypt_bits8[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+
+static uint32 saltbits;
+static long old_salt;
+static uint32 *bits28,
+		   *bits24;
+static uint8 init_perm[64],
+			final_perm[64];
+static uint32 en_keysl[16],
+			en_keysr[16];
+static uint32 de_keysl[16],
+			de_keysr[16];
+static int	des_initialised = 0;
+static uint8 m_sbox[4][4096];
+static uint32 psbox[4][256];
+static uint32 ip_maskl[8][256],
+			ip_maskr[8][256];
+static uint32 fp_maskl[8][256],
+			fp_maskr[8][256];
+static uint32 key_perm_maskl[8][128],
+			key_perm_maskr[8][128];
+static uint32 comp_maskl[8][128],
+			comp_maskr[8][128];
+static uint32 old_rawkey0,
+			old_rawkey1;
+
+static inline int
+ascii_to_bin(char ch)
+{
+	if (ch > 'z')
+		return (0);
+	if (ch >= 'a')
+		return (ch - 'a' + 38);
+	if (ch > 'Z')
+		return (0);
+	if (ch >= 'A')
+		return (ch - 'A' + 12);
+	if (ch > '9')
+		return (0);
+	if (ch >= '.')
+		return (ch - '.');
+	return (0);
+}
+
+static void
+des_init(void)
+{
+	int			i,
+				j,
+				b,
+				k,
+				inbit,
+				obit;
+	uint32	   *p,
+			   *il,
+			   *ir,
+			   *fl,
+			   *fr;
+
+	old_rawkey0 = old_rawkey1 = 0L;
+	saltbits = 0L;
+	old_salt = 0L;
+	bits24 = (bits28 = _crypt_bits32 + 4) + 4;
+
+	/*
+	 * Invert the S-boxes, reordering the input bits.
+	 */
+	for (i = 0; i < 8; i++)
+		for (j = 0; j < 64; j++)
+		{
+			b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
+			u_sbox[i][j] = sbox[i][b];
+		}
+
+	/*
+	 * Convert the inverted S-boxes into 4 arrays of 8 bits. Each will handle
+	 * 12 bits of the S-box input.
+	 */
+	for (b = 0; b < 4; b++)
+		for (i = 0; i < 64; i++)
+			for (j = 0; j < 64; j++)
+				m_sbox[b][(i << 6) | j] =
+					(u_sbox[(b << 1)][i] << 4) |
+					u_sbox[(b << 1) + 1][j];
+
+	/*
+	 * Set up the initial & final permutations into a useful form, and
+	 * initialise the inverted key permutation.
+	 */
+	for (i = 0; i < 64; i++)
+	{
+		init_perm[final_perm[i] = IP[i] - 1] = i;
+		inv_key_perm[i] = 255;
+	}
+
+	/*
+	 * Invert the key permutation and initialise the inverted key compression
+	 * permutation.
+	 */
+	for (i = 0; i < 56; i++)
+	{
+		u_key_perm[i] = key_perm[i] - 1;
+		inv_key_perm[key_perm[i] - 1] = i;
+		inv_comp_perm[i] = 255;
+	}
+
+	/*
+	 * Invert the key compression permutation.
+	 */
+	for (i = 0; i < 48; i++)
+		inv_comp_perm[comp_perm[i] - 1] = i;
+
+	/*
+	 * Set up the OR-mask arrays for the initial and final permutations, and
+	 * for the key initial and compression permutations.
+	 */
+	for (k = 0; k < 8; k++)
+	{
+		for (i = 0; i < 256; i++)
+		{
+			*(il = &ip_maskl[k][i]) = 0L;
+			*(ir = &ip_maskr[k][i]) = 0L;
+			*(fl = &fp_maskl[k][i]) = 0L;
+			*(fr = &fp_maskr[k][i]) = 0L;
+			for (j = 0; j < 8; j++)
+			{
+				inbit = 8 * k + j;
+				if (i & _crypt_bits8[j])
+				{
+					if ((obit = init_perm[inbit]) < 32)
+						*il |= _crypt_bits32[obit];
+					else
+						*ir |= _crypt_bits32[obit - 32];
+					if ((obit = final_perm[inbit]) < 32)
+						*fl |= _crypt_bits32[obit];
+					else
+						*fr |= _crypt_bits32[obit - 32];
+				}
+			}
+		}
+		for (i = 0; i < 128; i++)
+		{
+			*(il = &key_perm_maskl[k][i]) = 0L;
+			*(ir = &key_perm_maskr[k][i]) = 0L;
+			for (j = 0; j < 7; j++)
+			{
+				inbit = 8 * k + j;
+				if (i & _crypt_bits8[j + 1])
+				{
+					if ((obit = inv_key_perm[inbit]) == 255)
+						continue;
+					if (obit < 28)
+						*il |= bits28[obit];
+					else
+						*ir |= bits28[obit - 28];
+				}
+			}
+			*(il = &comp_maskl[k][i]) = 0L;
+			*(ir = &comp_maskr[k][i]) = 0L;
+			for (j = 0; j < 7; j++)
+			{
+				inbit = 7 * k + j;
+				if (i & _crypt_bits8[j + 1])
+				{
+					if ((obit = inv_comp_perm[inbit]) == 255)
+						continue;
+					if (obit < 24)
+						*il |= bits24[obit];
+					else
+						*ir |= bits24[obit - 24];
+				}
+			}
+		}
+	}
+
+	/*
+	 * Invert the P-box permutation, and convert into OR-masks for handling
+	 * the output of the S-box arrays setup above.
+	 */
+	for (i = 0; i < 32; i++)
+		un_pbox[pbox[i] - 1] = i;
+
+	for (b = 0; b < 4; b++)
+		for (i = 0; i < 256; i++)
+		{
+			*(p = &psbox[b][i]) = 0L;
+			for (j = 0; j < 8; j++)
+			{
+				if (i & _crypt_bits8[j])
+					*p |= _crypt_bits32[un_pbox[8 * b + j]];
+			}
+		}
+
+	des_initialised = 1;
+}
+
+static void
+setup_salt(long salt)
+{
+	uint32		obit,
+				saltbit;
+	int			i;
+
+	if (salt == old_salt)
+		return;
+	old_salt = salt;
+
+	saltbits = 0L;
+	saltbit = 1;
+	obit = 0x800000;
+	for (i = 0; i < 24; i++)
+	{
+		if (salt & saltbit)
+			saltbits |= obit;
+		saltbit <<= 1;
+		obit >>= 1;
+	}
+}
+
+static int
+des_setkey(const char *key)
+{
+	uint32		k0,
+				k1,
+				rawkey0,
+				rawkey1;
+	int			shifts,
+				round;
+
+	if (!des_initialised)
+		des_init();
+
+	rawkey0 = ntohl(*(const uint32 *) key);
+	rawkey1 = ntohl(*(const uint32 *) (key + 4));
+
+	if ((rawkey0 | rawkey1)
+		&& rawkey0 == old_rawkey0
+		&& rawkey1 == old_rawkey1)
+	{
+		/*
+		 * Already setup for this key. This optimisation fails on a zero key
+		 * (which is weak and has bad parity anyway) in order to simplify the
+		 * starting conditions.
+		 */
+		return (0);
+	}
+	old_rawkey0 = rawkey0;
+	old_rawkey1 = rawkey1;
+
+	/*
+	 * Do key permutation and split into two 28-bit subkeys.
+	 */
+	k0 = key_perm_maskl[0][rawkey0 >> 25]
+		| key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
+		| key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
+		| key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
+		| key_perm_maskl[4][rawkey1 >> 25]
+		| key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
+		| key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
+		| key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
+	k1 = key_perm_maskr[0][rawkey0 >> 25]
+		| key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
+		| key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
+		| key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
+		| key_perm_maskr[4][rawkey1 >> 25]
+		| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
+		| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
+		| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
+
+	/*
+	 * Rotate subkeys and do compression permutation.
+	 */
+	shifts = 0;
+	for (round = 0; round < 16; round++)
+	{
+		uint32		t0,
+					t1;
+
+		shifts += key_shifts[round];
+
+		t0 = (k0 << shifts) | (k0 >> (28 - shifts));
+		t1 = (k1 << shifts) | (k1 >> (28 - shifts));
+
+		de_keysl[15 - round] =
+			en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
+			| comp_maskl[1][(t0 >> 14) & 0x7f]
+			| comp_maskl[2][(t0 >> 7) & 0x7f]
+			| comp_maskl[3][t0 & 0x7f]
+			| comp_maskl[4][(t1 >> 21) & 0x7f]
+			| comp_maskl[5][(t1 >> 14) & 0x7f]
+			| comp_maskl[6][(t1 >> 7) & 0x7f]
+			| comp_maskl[7][t1 & 0x7f];
+
+		de_keysr[15 - round] =
+			en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
+			| comp_maskr[1][(t0 >> 14) & 0x7f]
+			| comp_maskr[2][(t0 >> 7) & 0x7f]
+			| comp_maskr[3][t0 & 0x7f]
+			| comp_maskr[4][(t1 >> 21) & 0x7f]
+			| comp_maskr[5][(t1 >> 14) & 0x7f]
+			| comp_maskr[6][(t1 >> 7) & 0x7f]
+			| comp_maskr[7][t1 & 0x7f];
+	}
+	return (0);
+}
+
+static int
+do_des(uint32 l_in, uint32 r_in, uint32 *l_out, uint32 *r_out, int count)
+{
+	/*
+	 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
+	 */
+	uint32		l,
+				r,
+			   *kl,
+			   *kr,
+			   *kl1,
+			   *kr1;
+	uint32		f,
+				r48l,
+				r48r;
+	int			round;
+
+	if (count == 0)
+		return (1);
+	else if (count > 0)
+	{
+		/*
+		 * Encrypting
+		 */
+		kl1 = en_keysl;
+		kr1 = en_keysr;
+	}
+	else
+	{
+		/*
+		 * Decrypting
+		 */
+		count = -count;
+		kl1 = de_keysl;
+		kr1 = de_keysr;
+	}
+
+	/*
+	 * Do initial permutation (IP).
+	 */
+	l = ip_maskl[0][l_in >> 24]
+		| ip_maskl[1][(l_in >> 16) & 0xff]
+		| ip_maskl[2][(l_in >> 8) & 0xff]
+		| ip_maskl[3][l_in & 0xff]
+		| ip_maskl[4][r_in >> 24]
+		| ip_maskl[5][(r_in >> 16) & 0xff]
+		| ip_maskl[6][(r_in >> 8) & 0xff]
+		| ip_maskl[7][r_in & 0xff];
+	r = ip_maskr[0][l_in >> 24]
+		| ip_maskr[1][(l_in >> 16) & 0xff]
+		| ip_maskr[2][(l_in >> 8) & 0xff]
+		| ip_maskr[3][l_in & 0xff]
+		| ip_maskr[4][r_in >> 24]
+		| ip_maskr[5][(r_in >> 16) & 0xff]
+		| ip_maskr[6][(r_in >> 8) & 0xff]
+		| ip_maskr[7][r_in & 0xff];
+
+	while (count--)
+	{
+		/*
+		 * Do each round.
+		 */
+		kl = kl1;
+		kr = kr1;
+		round = 16;
+		while (round--)
+		{
+			/*
+			 * Expand R to 48 bits (simulate the E-box).
+			 */
+			r48l = ((r & 0x00000001) << 23)
+				| ((r & 0xf8000000) >> 9)
+				| ((r & 0x1f800000) >> 11)
+				| ((r & 0x01f80000) >> 13)
+				| ((r & 0x001f8000) >> 15);
+
+			r48r = ((r & 0x0001f800) << 7)
+				| ((r & 0x00001f80) << 5)
+				| ((r & 0x000001f8) << 3)
+				| ((r & 0x0000001f) << 1)
+				| ((r & 0x80000000) >> 31);
+
+			/*
+			 * Do salting for crypt() and friends, and XOR with the permuted
+			 * key.
+			 */
+			f = (r48l ^ r48r) & saltbits;
+			r48l ^= f ^ *kl++;
+			r48r ^= f ^ *kr++;
+
+			/*
+			 * Do sbox lookups (which shrink it back to 32 bits) and do the
+			 * pbox permutation at the same time.
+			 */
+			f = psbox[0][m_sbox[0][r48l >> 12]]
+				| psbox[1][m_sbox[1][r48l & 0xfff]]
+				| psbox[2][m_sbox[2][r48r >> 12]]
+				| psbox[3][m_sbox[3][r48r & 0xfff]];
+
+			/*
+			 * Now that we've permuted things, complete f().
+			 */
+			f ^= l;
+			l = r;
+			r = f;
+		}
+		r = l;
+		l = f;
+	}
+
+	/*
+	 * Do final permutation (inverse of IP).
+	 */
+	*l_out = fp_maskl[0][l >> 24]
+		| fp_maskl[1][(l >> 16) & 0xff]
+		| fp_maskl[2][(l >> 8) & 0xff]
+		| fp_maskl[3][l & 0xff]
+		| fp_maskl[4][r >> 24]
+		| fp_maskl[5][(r >> 16) & 0xff]
+		| fp_maskl[6][(r >> 8) & 0xff]
+		| fp_maskl[7][r & 0xff];
+	*r_out = fp_maskr[0][l >> 24]
+		| fp_maskr[1][(l >> 16) & 0xff]
+		| fp_maskr[2][(l >> 8) & 0xff]
+		| fp_maskr[3][l & 0xff]
+		| fp_maskr[4][r >> 24]
+		| fp_maskr[5][(r >> 16) & 0xff]
+		| fp_maskr[6][(r >> 8) & 0xff]
+		| fp_maskr[7][r & 0xff];
+	return (0);
+}
+
+static int
+des_cipher(const char *in, char *out, long salt, int count)
+{
+	uint32		buffer[2];
+	uint32		l_out,
+				r_out,
+				rawl,
+				rawr;
+	int			retval;
+
+	if (!des_initialised)
+		des_init();
+
+	setup_salt(salt);
+
+	/* copy data to avoid assuming input is word-aligned */
+	memcpy(buffer, in, sizeof(buffer));
+
+	rawl = ntohl(buffer[0]);
+	rawr = ntohl(buffer[1]);
+
+	retval = do_des(rawl, rawr, &l_out, &r_out, count);
+
+	buffer[0] = htonl(l_out);
+	buffer[1] = htonl(r_out);
+
+	/* copy data to avoid assuming output is word-aligned */
+	memcpy(out, buffer, sizeof(buffer));
+
+	return (retval);
+}
+
+char *
+px_crypt_des(const char *key, const char *setting)
+{
+	int			i;
+	uint32		count,
+				salt,
+				l,
+				r0,
+				r1,
+				keybuf[2];
+	char	   *p;
+	uint8	   *q;
+	static char output[21];
+
+	if (!des_initialised)
+		des_init();
+
+
+	/*
+	 * Copy the key, shifting each character up by one bit and padding with
+	 * zeros.
+	 */
+	q = (uint8 *) keybuf;
+	while (q - (uint8 *) keybuf - 8)
+	{
+		*q++ = *key << 1;
+		if (*key != '\0')
+			key++;
+	}
+	if (des_setkey((char *) keybuf))
+		return (NULL);
+
+#ifndef DISABLE_XDES
+	if (*setting == _PASSWORD_EFMT1)
+	{
+		/*
+		 * "new"-style: setting - underscore, 4 bytes of count, 4 bytes of
+		 * salt key - unlimited characters
+		 */
+		for (i = 1, count = 0L; i < 5; i++)
+			count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
+
+		for (i = 5, salt = 0L; i < 9; i++)
+			salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
+
+		while (*key)
+		{
+			/*
+			 * Encrypt the key with itself.
+			 */
+			if (des_cipher((char *) keybuf, (char *) keybuf, 0L, 1))
+				return (NULL);
+
+			/*
+			 * And XOR with the next 8 characters of the key.
+			 */
+			q = (uint8 *) keybuf;
+			while (q - (uint8 *) keybuf - 8 && *key)
+				*q++ ^= *key++ << 1;
+
+			if (des_setkey((char *) keybuf))
+				return (NULL);
+		}
+		strncpy(output, setting, 9);
+
+		/*
+		 * Double check that we weren't given a short setting. If we were, the
+		 * above code will probably have created weird values for count and
+		 * salt, but we don't really care. Just make sure the output string
+		 * doesn't have an extra NUL in it.
+		 */
+		output[9] = '\0';
+		p = output + strlen(output);
+	}
+	else
+#endif   /* !DISABLE_XDES */
+	{
+		/*
+		 * "old"-style: setting - 2 bytes of salt key - up to 8 characters
+		 */
+		count = 25;
+
+		salt = (ascii_to_bin(setting[1]) << 6)
+			| ascii_to_bin(setting[0]);
+
+		output[0] = setting[0];
+
+		/*
+		 * If the encrypted password that the salt was extracted from is only
+		 * 1 character long, the salt will be corrupted.  We need to ensure
+		 * that the output string doesn't have an extra NUL in it!
+		 */
+		output[1] = setting[1] ? setting[1] : output[0];
+
+		p = output + 2;
+	}
+	setup_salt(salt);
+
+	/*
+	 * Do it.
+	 */
+	if (do_des(0L, 0L, &r0, &r1, count))
+		return (NULL);
+
+	/*
+	 * Now encode the result...
+	 */
+	l = (r0 >> 8);
+	*p++ = _crypt_a64[(l >> 18) & 0x3f];
+	*p++ = _crypt_a64[(l >> 12) & 0x3f];
+	*p++ = _crypt_a64[(l >> 6) & 0x3f];
+	*p++ = _crypt_a64[l & 0x3f];
+
+	l = (r0 << 16) | ((r1 >> 16) & 0xffff);
+	*p++ = _crypt_a64[(l >> 18) & 0x3f];
+	*p++ = _crypt_a64[(l >> 12) & 0x3f];
+	*p++ = _crypt_a64[(l >> 6) & 0x3f];
+	*p++ = _crypt_a64[l & 0x3f];
+
+	l = r1 << 2;
+	*p++ = _crypt_a64[(l >> 12) & 0x3f];
+	*p++ = _crypt_a64[(l >> 6) & 0x3f];
+	*p++ = _crypt_a64[l & 0x3f];
+	*p = 0;
+
+	return (output);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/crypt-gensalt.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/crypt-gensalt.c b/contrib/pgcrypto/crypt-gensalt.c
new file mode 100644
index 0000000..ec2e0fa
--- /dev/null
+++ b/contrib/pgcrypto/crypt-gensalt.c
@@ -0,0 +1,187 @@
+/*
+ * Written by Solar Designer and placed in the public domain.
+ * See crypt_blowfish.c for more information.
+ *
+ * contrib/pgcrypto/crypt-gensalt.c
+ *
+ * This file contains salt generation functions for the traditional and
+ * other common crypt(3) algorithms, except for bcrypt which is defined
+ * entirely in crypt_blowfish.c.
+ *
+ * Put bcrypt generator also here as crypt-blowfish.c
+ * may not be compiled always.		  -- marko
+ */
+
+#include "postgres.h"
+
+#include "px-crypt.h"
+
+typedef unsigned int BF_word;
+
+static unsigned char _crypt_itoa64[64 + 1] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+char *
+_crypt_gensalt_traditional_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	if (size < 2 || output_size < 2 + 1 || (count && count != 25))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	output[0] = _crypt_itoa64[(unsigned int) input[0] & 0x3f];
+	output[1] = _crypt_itoa64[(unsigned int) input[1] & 0x3f];
+	output[2] = '\0';
+
+	return output;
+}
+
+char *
+_crypt_gensalt_extended_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	unsigned long value;
+
+/* Even iteration counts make it easier to detect weak DES keys from a look
+ * at the hash, so they should be avoided */
+	if (size < 3 || output_size < 1 + 4 + 4 + 1 ||
+		(count && (count > 0xffffff || !(count & 1))))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	if (!count)
+		count = 725;
+
+	output[0] = '_';
+	output[1] = _crypt_itoa64[count & 0x3f];
+	output[2] = _crypt_itoa64[(count >> 6) & 0x3f];
+	output[3] = _crypt_itoa64[(count >> 12) & 0x3f];
+	output[4] = _crypt_itoa64[(count >> 18) & 0x3f];
+	value = (unsigned long) (unsigned char) input[0] |
+		((unsigned long) (unsigned char) input[1] << 8) |
+		((unsigned long) (unsigned char) input[2] << 16);
+	output[5] = _crypt_itoa64[value & 0x3f];
+	output[6] = _crypt_itoa64[(value >> 6) & 0x3f];
+	output[7] = _crypt_itoa64[(value >> 12) & 0x3f];
+	output[8] = _crypt_itoa64[(value >> 18) & 0x3f];
+	output[9] = '\0';
+
+	return output;
+}
+
+char *
+_crypt_gensalt_md5_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	unsigned long value;
+
+	if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	output[0] = '$';
+	output[1] = '1';
+	output[2] = '$';
+	value = (unsigned long) (unsigned char) input[0] |
+		((unsigned long) (unsigned char) input[1] << 8) |
+		((unsigned long) (unsigned char) input[2] << 16);
+	output[3] = _crypt_itoa64[value & 0x3f];
+	output[4] = _crypt_itoa64[(value >> 6) & 0x3f];
+	output[5] = _crypt_itoa64[(value >> 12) & 0x3f];
+	output[6] = _crypt_itoa64[(value >> 18) & 0x3f];
+	output[7] = '\0';
+
+	if (size >= 6 && output_size >= 3 + 4 + 4 + 1)
+	{
+		value = (unsigned long) (unsigned char) input[3] |
+			((unsigned long) (unsigned char) input[4] << 8) |
+			((unsigned long) (unsigned char) input[5] << 16);
+		output[7] = _crypt_itoa64[value & 0x3f];
+		output[8] = _crypt_itoa64[(value >> 6) & 0x3f];
+		output[9] = _crypt_itoa64[(value >> 12) & 0x3f];
+		output[10] = _crypt_itoa64[(value >> 18) & 0x3f];
+		output[11] = '\0';
+	}
+
+	return output;
+}
+
+
+
+static unsigned char BF_itoa64[64 + 1] =
+"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static void
+BF_encode(char *dst, const BF_word *src, int size)
+{
+	const unsigned char *sptr = (const unsigned char *) src;
+	const unsigned char *end = sptr + size;
+	unsigned char *dptr = (unsigned char *) dst;
+	unsigned int c1,
+				c2;
+
+	do
+	{
+		c1 = *sptr++;
+		*dptr++ = BF_itoa64[c1 >> 2];
+		c1 = (c1 & 0x03) << 4;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 4;
+		*dptr++ = BF_itoa64[c1];
+		c1 = (c2 & 0x0f) << 2;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 6;
+		*dptr++ = BF_itoa64[c1];
+		*dptr++ = BF_itoa64[c2 & 0x3f];
+	} while (sptr < end);
+}
+
+char *
+_crypt_gensalt_blowfish_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	if (size < 16 || output_size < 7 + 22 + 1 ||
+		(count && (count < 4 || count > 31)))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	if (!count)
+		count = 5;
+
+	output[0] = '$';
+	output[1] = '2';
+	output[2] = 'a';
+	output[3] = '$';
+	output[4] = '0' + count / 10;
+	output[5] = '0' + count % 10;
+	output[6] = '$';
+
+	BF_encode(&output[7], (const BF_word *) input, 16);
+	output[7 + 22] = '\0';
+
+	return output;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/crypt-md5.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/crypt-md5.c b/contrib/pgcrypto/crypt-md5.c
new file mode 100644
index 0000000..6c7a2b3
--- /dev/null
+++ b/contrib/pgcrypto/crypt-md5.c
@@ -0,0 +1,163 @@
+/*
+ * File imported from FreeBSD, original by Poul-Henning Kamp.
+ *
+ * $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
+ *
+ * contrib/pgcrypto/crypt-md5.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "px-crypt.h"
+
+#define MD5_SIZE 16
+
+static const char _crypt_a64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void
+_crypt_to64(char *s, unsigned long v, int n)
+{
+	while (--n >= 0)
+	{
+		*s++ = _crypt_a64[v & 0x3f];
+		v >>= 6;
+	}
+}
+
+/*
+ * UNIX password
+ */
+
+char *
+px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen)
+{
+	static char *magic = "$1$"; /* This string is magic for this algorithm.
+								 * Having it this way, we can get better
+								 * later on */
+	static char *p;
+	static const char *sp,
+			   *ep;
+	unsigned char final[MD5_SIZE];
+	int			sl,
+				pl,
+				i;
+	PX_MD	   *ctx,
+			   *ctx1;
+	int			err;
+	unsigned long l;
+
+	if (!passwd || dstlen < 120)
+		return NULL;
+
+	/* Refine the Salt first */
+	sp = salt;
+
+	/* If it starts with the magic string, then skip that */
+	if (strncmp(sp, magic, strlen(magic)) == 0)
+		sp += strlen(magic);
+
+	/* It stops at the first '$', max 8 chars */
+	for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
+		continue;
+
+	/* get the length of the true salt */
+	sl = ep - sp;
+
+	/* */
+	err = px_find_digest("md5", &ctx);
+	if (err)
+		return NULL;
+	err = px_find_digest("md5", &ctx1);
+
+	/* The password first, since that is what is most unknown */
+	px_md_update(ctx, (const uint8 *) pw, strlen(pw));
+
+	/* Then our magic string */
+	px_md_update(ctx, (uint8 *) magic, strlen(magic));
+
+	/* Then the raw salt */
+	px_md_update(ctx, (const uint8 *) sp, sl);
+
+	/* Then just as many characters of the MD5(pw,salt,pw) */
+	px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+	px_md_update(ctx1, (const uint8 *) sp, sl);
+	px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+	px_md_finish(ctx1, final);
+	for (pl = strlen(pw); pl > 0; pl -= MD5_SIZE)
+		px_md_update(ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl);
+
+	/* Don't leave anything around in vm they could use. */
+	memset(final, 0, sizeof final);
+
+	/* Then something really weird... */
+	for (i = strlen(pw); i; i >>= 1)
+		if (i & 1)
+			px_md_update(ctx, final, 1);
+		else
+			px_md_update(ctx, (const uint8 *) pw, 1);
+
+	/* Now make the output string */
+	strcpy(passwd, magic);
+	strncat(passwd, sp, sl);
+	strcat(passwd, "$");
+
+	px_md_finish(ctx, final);
+
+	/*
+	 * and now, just to make sure things don't run too fast On a 60 Mhz
+	 * Pentium this takes 34 msec, so you would need 30 seconds to build a
+	 * 1000 entry dictionary...
+	 */
+	for (i = 0; i < 1000; i++)
+	{
+		px_md_reset(ctx1);
+		if (i & 1)
+			px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+		else
+			px_md_update(ctx1, final, MD5_SIZE);
+
+		if (i % 3)
+			px_md_update(ctx1, (const uint8 *) sp, sl);
+
+		if (i % 7)
+			px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+
+		if (i & 1)
+			px_md_update(ctx1, final, MD5_SIZE);
+		else
+			px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+		px_md_finish(ctx1, final);
+	}
+
+	p = passwd + strlen(passwd);
+
+	l = (final[0] << 16) | (final[6] << 8) | final[12];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[1] << 16) | (final[7] << 8) | final[13];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[2] << 16) | (final[8] << 8) | final[14];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[3] << 16) | (final[9] << 8) | final[15];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[4] << 16) | (final[10] << 8) | final[5];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = final[11];
+	_crypt_to64(p, l, 2);
+	p += 2;
+	*p = '\0';
+
+	/* Don't leave anything around in vm they could use. */
+	memset(final, 0, sizeof final);
+
+	px_md_free(ctx1);
+	px_md_free(ctx);
+
+	return passwd;
+}



[09/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/sha2.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/sha2.out b/contrib/pgcrypto/expected/sha2.out
new file mode 100644
index 0000000..2df5a0d
--- /dev/null
+++ b/contrib/pgcrypto/expected/sha2.out
@@ -0,0 +1,139 @@
+--
+-- SHA2 family
+--
+-- SHA224
+SELECT encode(digest('', 'sha224'), 'hex');
+                          encode                          
+----------------------------------------------------------
+ d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f
+(1 row)
+
+SELECT encode(digest('a', 'sha224'), 'hex');
+                          encode                          
+----------------------------------------------------------
+ abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5
+(1 row)
+
+SELECT encode(digest('abc', 'sha224'), 'hex');
+                          encode                          
+----------------------------------------------------------
+ 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
+(1 row)
+
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha224'), 'hex');
+                          encode                          
+----------------------------------------------------------
+ 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525
+(1 row)
+
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha224'), 'hex');
+                          encode                          
+----------------------------------------------------------
+ b50aecbe4e9bb0b57bc5f3ae760a8e01db24f203fb3cdcd13148046e
+(1 row)
+
+-- SHA256
+SELECT encode(digest('', 'sha256'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+(1 row)
+
+SELECT encode(digest('a', 'sha256'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
+(1 row)
+
+SELECT encode(digest('abc', 'sha256'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
+(1 row)
+
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha256'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1
+(1 row)
+
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha256'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ f371bc4a311f2b009eef952dd83ca80e2b60026c8e935592d0f9c308453c813e
+(1 row)
+
+-- SHA384
+SELECT encode(digest('', 'sha384'), 'hex');
+                                              encode                                              
+--------------------------------------------------------------------------------------------------
+ 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b
+(1 row)
+
+SELECT encode(digest('a', 'sha384'), 'hex');
+                                              encode                                              
+--------------------------------------------------------------------------------------------------
+ 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31
+(1 row)
+
+SELECT encode(digest('abc', 'sha384'), 'hex');
+                                              encode                                              
+--------------------------------------------------------------------------------------------------
+ cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
+(1 row)
+
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha384'), 'hex');
+                                              encode                                              
+--------------------------------------------------------------------------------------------------
+ 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b
+(1 row)
+
+SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha384'), 'hex');
+                                              encode                                              
+--------------------------------------------------------------------------------------------------
+ 09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039
+(1 row)
+
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha384'), 'hex');
+                                              encode                                              
+--------------------------------------------------------------------------------------------------
+ 3d208973ab3508dbbd7e2c2862ba290ad3010e4978c198dc4d8fd014e582823a89e16f9b2a7bbc1ac938e2d199e8bea4
+(1 row)
+
+-- SHA512
+SELECT encode(digest('', 'sha512'), 'hex');
+                                                              encode                                                              
+----------------------------------------------------------------------------------------------------------------------------------
+ cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
+(1 row)
+
+SELECT encode(digest('a', 'sha512'), 'hex');
+                                                              encode                                                              
+----------------------------------------------------------------------------------------------------------------------------------
+ 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75
+(1 row)
+
+SELECT encode(digest('abc', 'sha512'), 'hex');
+                                                              encode                                                              
+----------------------------------------------------------------------------------------------------------------------------------
+ ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
+(1 row)
+
+SELECT encode(digest('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq', 'sha512'), 'hex');
+                                                              encode                                                              
+----------------------------------------------------------------------------------------------------------------------------------
+ 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445
+(1 row)
+
+SELECT encode(digest('abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu', 'sha512'), 'hex');
+                                                              encode                                                              
+----------------------------------------------------------------------------------------------------------------------------------
+ 8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909
+(1 row)
+
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz', 'sha512'), 'hex');
+                                                              encode                                                              
+----------------------------------------------------------------------------------------------------------------------------------
+ 930d0cefcb30ff1133b6898121f1cf3d27578afcafe8677c5257cf069911f75d8f5831b56ebfda67b278e66dff8b84fe2b2870f742a580d8edb41987232850c9
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/fortuna.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/fortuna.c b/contrib/pgcrypto/fortuna.c
new file mode 100644
index 0000000..1228fb4
--- /dev/null
+++ b/contrib/pgcrypto/fortuna.c
@@ -0,0 +1,462 @@
+/*
+ * fortuna.c
+ *		Fortuna-like PRNG.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/fortuna.c
+ */
+
+#include "postgres.h"
+
+#include <sys/time.h>
+#include <time.h>
+
+#include "rijndael.h"
+#include "sha2.h"
+#include "fortuna.h"
+
+
+/*
+ * Why Fortuna-like: There does not seem to be any definitive reference
+ * on Fortuna in the net.  Instead this implementation is based on
+ * following references:
+ *
+ * http://en.wikipedia.org/wiki/Fortuna_(PRNG)
+ *	 - Wikipedia article
+ * http://jlcooke.ca/random/
+ *	 - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
+ */
+
+/*
+ * There is some confusion about whether and how to carry forward
+ * the state of the pools.	Seems like original Fortuna does not
+ * do it, resetting hash after each request.  I guess expecting
+ * feeding to happen more often that requesting.   This is absolutely
+ * unsuitable for pgcrypto, as nothing asynchronous happens here.
+ *
+ * J.L. Cooke fixed this by feeding previous hash to new re-initialized
+ * hash context.
+ *
+ * Fortuna predecessor Yarrow requires ability to query intermediate
+ * 'final result' from hash, without affecting it.
+ *
+ * This implementation uses the Yarrow method - asking intermediate
+ * results, but continuing with old state.
+ */
+
+
+/*
+ * Algorithm parameters
+ */
+
+/*
+ * How many pools.
+ *
+ * Original Fortuna uses 32 pools, that means 32'th pool is
+ * used not earlier than in 13th year.	This is a waste in
+ * pgcrypto, as we have very low-frequancy seeding.  Here
+ * is preferable to have all entropy usable in reasonable time.
+ *
+ * With 23 pools, 23th pool is used after 9 days which seems
+ * more sane.
+ *
+ * In our case the minimal cycle time would be bit longer
+ * than the system-randomness feeding frequency.
+ */
+#define NUM_POOLS		23
+
+/* in microseconds */
+#define RESEED_INTERVAL 100000	/* 0.1 sec */
+
+/* for one big request, reseed after this many bytes */
+#define RESEED_BYTES	(1024*1024)
+
+/*
+ * Skip reseed if pool 0 has less than this many
+ * bytes added since last reseed.
+ */
+#define POOL0_FILL		(256/8)
+
+/*
+ * Algorithm constants
+ */
+
+/* Both cipher key size and hash result size */
+#define BLOCK			32
+
+/* cipher block size */
+#define CIPH_BLOCK		16
+
+/* for internal wrappers */
+#define MD_CTX			SHA256_CTX
+#define CIPH_CTX		rijndael_ctx
+
+struct fortuna_state
+{
+	uint8		counter[CIPH_BLOCK];
+	uint8		result[CIPH_BLOCK];
+	uint8		key[BLOCK];
+	MD_CTX		pool[NUM_POOLS];
+	CIPH_CTX	ciph;
+	unsigned	reseed_count;
+	struct timeval last_reseed_time;
+	unsigned	pool0_bytes;
+	unsigned	rnd_pos;
+	int			tricks_done;
+};
+typedef struct fortuna_state FState;
+
+
+/*
+ * Use our own wrappers here.
+ * - Need to get intermediate result from digest, without affecting it.
+ * - Need re-set key on a cipher context.
+ * - Algorithms are guaranteed to exist.
+ * - No memory allocations.
+ */
+
+static void
+ciph_init(CIPH_CTX * ctx, const uint8 *key, int klen)
+{
+	rijndael_set_key(ctx, (const uint32 *) key, klen, 1);
+}
+
+static void
+ciph_encrypt(CIPH_CTX * ctx, const uint8 *in, uint8 *out)
+{
+	rijndael_encrypt(ctx, (const uint32 *) in, (uint32 *) out);
+}
+
+static void
+md_init(MD_CTX * ctx)
+{
+	SHA256_Init(ctx);
+}
+
+static void
+md_update(MD_CTX * ctx, const uint8 *data, int len)
+{
+	SHA256_Update(ctx, data, len);
+}
+
+static void
+md_result(MD_CTX * ctx, uint8 *dst)
+{
+	SHA256_CTX	tmp;
+
+	memcpy(&tmp, ctx, sizeof(*ctx));
+	SHA256_Final(dst, &tmp);
+	memset(&tmp, 0, sizeof(tmp));
+}
+
+/*
+ * initialize state
+ */
+static void
+init_state(FState *st)
+{
+	int			i;
+
+	memset(st, 0, sizeof(*st));
+	for (i = 0; i < NUM_POOLS; i++)
+		md_init(&st->pool[i]);
+}
+
+/*
+ * Endianess does not matter.
+ * It just needs to change without repeating.
+ */
+static void
+inc_counter(FState *st)
+{
+	uint32	   *val = (uint32 *) st->counter;
+
+	if (++val[0])
+		return;
+	if (++val[1])
+		return;
+	if (++val[2])
+		return;
+	++val[3];
+}
+
+/*
+ * This is called 'cipher in counter mode'.
+ */
+static void
+encrypt_counter(FState *st, uint8 *dst)
+{
+	ciph_encrypt(&st->ciph, st->counter, dst);
+	inc_counter(st);
+}
+
+
+/*
+ * The time between reseed must be at least RESEED_INTERVAL
+ * microseconds.
+ */
+static int
+enough_time_passed(FState *st)
+{
+	int			ok;
+	struct timeval tv;
+	struct timeval *last = &st->last_reseed_time;
+
+	gettimeofday(&tv, NULL);
+
+	/* check how much time has passed */
+	ok = 0;
+	if (tv.tv_sec > last->tv_sec + 1)
+		ok = 1;
+	else if (tv.tv_sec == last->tv_sec + 1)
+	{
+		if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+			ok = 1;
+	}
+	else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
+		ok = 1;
+
+	/* reseed will happen, update last_reseed_time */
+	if (ok)
+		memcpy(last, &tv, sizeof(tv));
+
+	memset(&tv, 0, sizeof(tv));
+
+	return ok;
+}
+
+/*
+ * generate new key from all the pools
+ */
+static void
+reseed(FState *st)
+{
+	unsigned	k;
+	unsigned	n;
+	MD_CTX		key_md;
+	uint8		buf[BLOCK];
+
+	/* set pool as empty */
+	st->pool0_bytes = 0;
+
+	/*
+	 * Both #0 and #1 reseed would use only pool 0. Just skip #0 then.
+	 */
+	n = ++st->reseed_count;
+
+	/*
+	 * The goal: use k-th pool only 1/(2^k) of the time.
+	 */
+	md_init(&key_md);
+	for (k = 0; k < NUM_POOLS; k++)
+	{
+		md_result(&st->pool[k], buf);
+		md_update(&key_md, buf, BLOCK);
+
+		if (n & 1 || !n)
+			break;
+		n >>= 1;
+	}
+
+	/* add old key into mix too */
+	md_update(&key_md, st->key, BLOCK);
+
+	/* now we have new key */
+	md_result(&key_md, st->key);
+
+	/* use new key */
+	ciph_init(&st->ciph, st->key, BLOCK);
+
+	memset(&key_md, 0, sizeof(key_md));
+	memset(buf, 0, BLOCK);
+}
+
+/*
+ * Pick a random pool.	This uses key bytes as random source.
+ */
+static unsigned
+get_rand_pool(FState *st)
+{
+	unsigned	rnd;
+
+	/*
+	 * This slightly prefers lower pools - thats OK.
+	 */
+	rnd = st->key[st->rnd_pos] % NUM_POOLS;
+
+	st->rnd_pos++;
+	if (st->rnd_pos >= BLOCK)
+		st->rnd_pos = 0;
+
+	return rnd;
+}
+
+/*
+ * update pools
+ */
+static void
+add_entropy(FState *st, const uint8 *data, unsigned len)
+{
+	unsigned	pos;
+	uint8		hash[BLOCK];
+	MD_CTX		md;
+
+	/* hash given data */
+	md_init(&md);
+	md_update(&md, data, len);
+	md_result(&md, hash);
+
+	/*
+	 * Make sure the pool 0 is initialized, then update randomly.
+	 */
+	if (st->reseed_count == 0)
+		pos = 0;
+	else
+		pos = get_rand_pool(st);
+	md_update(&st->pool[pos], hash, BLOCK);
+
+	if (pos == 0)
+		st->pool0_bytes += len;
+
+	memset(hash, 0, BLOCK);
+	memset(&md, 0, sizeof(md));
+}
+
+/*
+ * Just take 2 next blocks as new key
+ */
+static void
+rekey(FState *st)
+{
+	encrypt_counter(st, st->key);
+	encrypt_counter(st, st->key + CIPH_BLOCK);
+	ciph_init(&st->ciph, st->key, BLOCK);
+}
+
+/*
+ * Hide public constants. (counter, pools > 0)
+ *
+ * This can also be viewed as spreading the startup
+ * entropy over all of the components.
+ */
+static void
+startup_tricks(FState *st)
+{
+	int			i;
+	uint8		buf[BLOCK];
+
+	/* Use next block as counter. */
+	encrypt_counter(st, st->counter);
+
+	/* Now shuffle pools, excluding #0 */
+	for (i = 1; i < NUM_POOLS; i++)
+	{
+		encrypt_counter(st, buf);
+		encrypt_counter(st, buf + CIPH_BLOCK);
+		md_update(&st->pool[i], buf, BLOCK);
+	}
+	memset(buf, 0, BLOCK);
+
+	/* Hide the key. */
+	rekey(st);
+
+	/* This can be done only once. */
+	st->tricks_done = 1;
+}
+
+static void
+extract_data(FState *st, unsigned count, uint8 *dst)
+{
+	unsigned	n;
+	unsigned	block_nr = 0;
+
+	/* Should we reseed? */
+	if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0)
+		if (enough_time_passed(st))
+			reseed(st);
+
+	/* Do some randomization on first call */
+	if (!st->tricks_done)
+		startup_tricks(st);
+
+	while (count > 0)
+	{
+		/* produce bytes */
+		encrypt_counter(st, st->result);
+
+		/* copy result */
+		if (count > CIPH_BLOCK)
+			n = CIPH_BLOCK;
+		else
+			n = count;
+		memcpy(dst, st->result, n);
+		dst += n;
+		count -= n;
+
+		/* must not give out too many bytes with one key */
+		block_nr++;
+		if (block_nr > (RESEED_BYTES / CIPH_BLOCK))
+		{
+			rekey(st);
+			block_nr = 0;
+		}
+	}
+	/* Set new key for next request. */
+	rekey(st);
+}
+
+/*
+ * public interface
+ */
+
+static FState main_state;
+static int	init_done = 0;
+
+void
+fortuna_add_entropy(const uint8 *data, unsigned len)
+{
+	if (!init_done)
+	{
+		init_state(&main_state);
+		init_done = 1;
+	}
+	if (!data || !len)
+		return;
+	add_entropy(&main_state, data, len);
+}
+
+void
+fortuna_get_bytes(unsigned len, uint8 *dst)
+{
+	if (!init_done)
+	{
+		init_state(&main_state);
+		init_done = 1;
+	}
+	if (!dst || !len)
+		return;
+	extract_data(&main_state, len, dst);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/fortuna.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/fortuna.h b/contrib/pgcrypto/fortuna.h
new file mode 100644
index 0000000..2e49f8a
--- /dev/null
+++ b/contrib/pgcrypto/fortuna.h
@@ -0,0 +1,38 @@
+/*
+ * fortuna.c
+ *		Fortuna PRNG.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/fortuna.h
+ */
+
+#ifndef __FORTUNA_H
+#define __FORTUNA_H
+
+void		fortuna_get_bytes(unsigned len, uint8 *dst);
+void		fortuna_add_entropy(const uint8 *data, unsigned len);
+
+#endif


[04/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/px.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c
new file mode 100644
index 0000000..f23d4de
--- /dev/null
+++ b/contrib/pgcrypto/px.c
@@ -0,0 +1,437 @@
+/*
+ * px.c
+ *		Various cryptographic stuff for PostgreSQL.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/px.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+
+struct error_desc
+{
+	int			err;
+	const char *desc;
+};
+
+static const struct error_desc px_err_list[] = {
+	{PXE_OK, "Everything ok"},
+	{PXE_ERR_GENERIC, "Some PX error (not specified)"},
+	{PXE_NO_HASH, "No such hash algorithm"},
+	{PXE_NO_CIPHER, "No such cipher algorithm"},
+	{PXE_NOTBLOCKSIZE, "Data not a multiple of block size"},
+	{PXE_BAD_OPTION, "Unknown option"},
+	{PXE_BAD_FORMAT, "Badly formatted type"},
+	{PXE_KEY_TOO_BIG, "Key was too big"},
+	{PXE_CIPHER_INIT, "Cipher cannot be initalized ?"},
+	{PXE_HASH_UNUSABLE_FOR_HMAC, "This hash algorithm is unusable for HMAC"},
+	{PXE_DEV_READ_ERROR, "Error reading from random device"},
+	{PXE_OSSL_RAND_ERROR, "OpenSSL PRNG error"},
+	{PXE_BUG, "pgcrypto bug"},
+	{PXE_ARGUMENT_ERROR, "Illegal argument to function"},
+	{PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"},
+	{PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"},
+	{PXE_MCRYPT_INTERNAL, "mcrypt internal error"},
+	{PXE_NO_RANDOM, "No strong random source"},
+	{PXE_DECRYPT_FAILED, "Decryption failed"},
+	{PXE_PGP_CORRUPT_DATA, "Wrong key or corrupt data"},
+	{PXE_PGP_CORRUPT_ARMOR, "Corrupt ascii-armor"},
+	{PXE_PGP_UNSUPPORTED_COMPR, "Unsupported compression algorithm"},
+	{PXE_PGP_UNSUPPORTED_CIPHER, "Unsupported cipher algorithm"},
+	{PXE_PGP_UNSUPPORTED_HASH, "Unsupported digest algorithm"},
+	{PXE_PGP_COMPRESSION_ERROR, "Compression error"},
+	{PXE_PGP_NOT_TEXT, "Not text data"},
+	{PXE_PGP_UNEXPECTED_PKT, "Unexpected packet in key data"},
+	{PXE_PGP_NO_BIGNUM,
+		"public-key functions disabled - "
+	"pgcrypto needs OpenSSL for bignums"},
+	{PXE_PGP_MATH_FAILED, "Math operation failed"},
+	{PXE_PGP_SHORT_ELGAMAL_KEY, "Elgamal keys must be at least 1024 bits long"},
+	{PXE_PGP_RSA_UNSUPPORTED, "pgcrypto does not support RSA keys"},
+	{PXE_PGP_UNKNOWN_PUBALGO, "Unknown public-key encryption algorithm"},
+	{PXE_PGP_WRONG_KEY, "Wrong key"},
+	{PXE_PGP_MULTIPLE_KEYS,
+	"Several keys given - pgcrypto does not handle keyring"},
+	{PXE_PGP_EXPECT_PUBLIC_KEY, "Refusing to encrypt with secret key"},
+	{PXE_PGP_EXPECT_SECRET_KEY, "Cannot decrypt with public key"},
+	{PXE_PGP_NOT_V4_KEYPKT, "Only V4 key packets are supported"},
+	{PXE_PGP_KEYPKT_CORRUPT, "Corrupt key packet"},
+	{PXE_PGP_NO_USABLE_KEY, "No encryption key found"},
+	{PXE_PGP_NEED_SECRET_PSW, "Need password for secret key"},
+	{PXE_PGP_BAD_S2K_MODE, "Bad S2K mode"},
+	{PXE_PGP_UNSUPPORTED_PUBALGO, "Unsupported public key algorithm"},
+	{PXE_PGP_MULTIPLE_SUBKEYS, "Several subkeys not supported"},
+
+	/* fake this as PXE_PGP_CORRUPT_DATA */
+	{PXE_MBUF_SHORT_READ, "Corrupt data"},
+
+	{0, NULL},
+};
+
+const char *
+px_strerror(int err)
+{
+	const struct error_desc *e;
+
+	for (e = px_err_list; e->desc; e++)
+		if (e->err == err)
+			return e->desc;
+	return "Bad error code";
+}
+
+
+const char *
+px_resolve_alias(const PX_Alias *list, const char *name)
+{
+	while (list->name)
+	{
+		if (pg_strcasecmp(list->alias, name) == 0)
+			return list->name;
+		list++;
+	}
+	return name;
+}
+
+static void (*debug_handler) (const char *) = NULL;
+
+void
+px_set_debug_handler(void (*handler) (const char *))
+{
+	debug_handler = handler;
+}
+
+void
+px_debug(const char *fmt,...)
+{
+	va_list		ap;
+
+	va_start(ap, fmt);
+	if (debug_handler)
+	{
+		char		buf[512];
+
+		vsnprintf(buf, sizeof(buf), fmt, ap);
+		debug_handler(buf);
+	}
+	va_end(ap);
+}
+
+/*
+ * combo - cipher + padding (+ checksum)
+ */
+
+static unsigned
+combo_encrypt_len(PX_Combo *cx, unsigned dlen)
+{
+	return dlen + 512;
+}
+
+static unsigned
+combo_decrypt_len(PX_Combo *cx, unsigned dlen)
+{
+	return dlen;
+}
+
+static int
+combo_init(PX_Combo *cx, const uint8 *key, unsigned klen,
+		   const uint8 *iv, unsigned ivlen)
+{
+	int			err;
+	unsigned	ks,
+				ivs;
+	PX_Cipher  *c = cx->cipher;
+	uint8	   *ivbuf = NULL;
+	uint8	   *keybuf;
+
+	ks = px_cipher_key_size(c);
+
+	ivs = px_cipher_iv_size(c);
+	if (ivs > 0)
+	{
+		ivbuf = px_alloc(ivs);
+		memset(ivbuf, 0, ivs);
+		if (ivlen > ivs)
+			memcpy(ivbuf, iv, ivs);
+		else
+			memcpy(ivbuf, iv, ivlen);
+	}
+
+	if (klen > ks)
+		klen = ks;
+	keybuf = px_alloc(ks);
+	memset(keybuf, 0, ks);
+	memcpy(keybuf, key, klen);
+
+	err = px_cipher_init(c, keybuf, klen, ivbuf);
+
+	if (ivbuf)
+		px_free(ivbuf);
+	px_free(keybuf);
+
+	return err;
+}
+
+static int
+combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
+			  uint8 *res, unsigned *rlen)
+{
+	int			err = 0;
+	uint8	   *bbuf;
+	unsigned	bs,
+				bpos,
+				i,
+				pad;
+
+	PX_Cipher  *c = cx->cipher;
+
+	bbuf = NULL;
+	bs = px_cipher_block_size(c);
+
+	/* encrypt */
+	if (bs > 1)
+	{
+		bbuf = px_alloc(bs * 4);
+		bpos = dlen % bs;
+		*rlen = dlen - bpos;
+		memcpy(bbuf, data + *rlen, bpos);
+
+		/* encrypt full-block data */
+		if (*rlen)
+		{
+			err = px_cipher_encrypt(c, data, *rlen, res);
+			if (err)
+				goto out;
+		}
+
+		/* bbuf has now bpos bytes of stuff */
+		if (cx->padding)
+		{
+			pad = bs - (bpos % bs);
+			for (i = 0; i < pad; i++)
+				bbuf[bpos++] = pad;
+		}
+		else if (bpos % bs)
+		{
+			/* ERROR? */
+			pad = bs - (bpos % bs);
+			for (i = 0; i < pad; i++)
+				bbuf[bpos++] = 0;
+		}
+
+		/* encrypt the rest - pad */
+		if (bpos)
+		{
+			err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen);
+			*rlen += bpos;
+		}
+	}
+	else
+	{
+		/* stream cipher/mode - no pad needed */
+		err = px_cipher_encrypt(c, data, dlen, res);
+		if (err)
+			goto out;
+		*rlen = dlen;
+	}
+out:
+	if (bbuf)
+		px_free(bbuf);
+
+	return err;
+}
+
+static int
+combo_decrypt(PX_Combo *cx, const uint8 *data, unsigned dlen,
+			  uint8 *res, unsigned *rlen)
+{
+	unsigned	bs,
+				i,
+				pad;
+	unsigned	pad_ok;
+
+	PX_Cipher  *c = cx->cipher;
+
+	/* decide whether zero-length input is allowed */
+	if (dlen == 0)
+	{
+		/* with padding, empty ciphertext is not allowed */
+		if (cx->padding)
+			return PXE_DECRYPT_FAILED;
+
+		/* without padding, report empty result */
+		*rlen = 0;
+		return 0;
+	}
+
+	bs = px_cipher_block_size(c);
+	if (bs > 1 && (dlen % bs) != 0)
+		goto block_error;
+
+	/* decrypt */
+	*rlen = dlen;
+	px_cipher_decrypt(c, data, dlen, res);
+
+	/* unpad */
+	if (bs > 1 && cx->padding)
+	{
+		pad = res[*rlen - 1];
+		pad_ok = 0;
+		if (pad > 0 && pad <= bs && pad <= *rlen)
+		{
+			pad_ok = 1;
+			for (i = *rlen - pad; i < *rlen; i++)
+				if (res[i] != pad)
+				{
+					pad_ok = 0;
+					break;
+				}
+		}
+
+		if (pad_ok)
+			*rlen -= pad;
+	}
+
+	return 0;
+
+block_error:
+	return PXE_NOTBLOCKSIZE;
+}
+
+static void
+combo_free(PX_Combo *cx)
+{
+	if (cx->cipher)
+		px_cipher_free(cx->cipher);
+	memset(cx, 0, sizeof(*cx));
+	px_free(cx);
+}
+
+/* PARSER */
+
+static int
+parse_cipher_name(char *full, char **cipher, char **pad)
+{
+	char	   *p,
+			   *p2,
+			   *q;
+
+	*cipher = full;
+	*pad = NULL;
+
+	p = strchr(full, '/');
+	if (p != NULL)
+		*p++ = 0;
+	while (p != NULL)
+	{
+		if ((q = strchr(p, '/')) != NULL)
+			*q++ = 0;
+
+		if (!*p)
+		{
+			p = q;
+			continue;
+		}
+		p2 = strchr(p, ':');
+		if (p2 != NULL)
+		{
+			*p2++ = 0;
+			if (strcmp(p, "pad") == 0)
+				*pad = p2;
+			else
+				return PXE_BAD_OPTION;
+		}
+		else
+			return PXE_BAD_FORMAT;
+
+		p = q;
+	}
+	return 0;
+}
+
+/* provider */
+
+int
+px_find_combo(const char *name, PX_Combo **res)
+{
+	int			err;
+	char	   *buf,
+			   *s_cipher,
+			   *s_pad;
+
+	PX_Combo   *cx;
+
+	cx = px_alloc(sizeof(*cx));
+	memset(cx, 0, sizeof(*cx));
+
+	buf = px_alloc(strlen(name) + 1);
+	strcpy(buf, name);
+
+	err = parse_cipher_name(buf, &s_cipher, &s_pad);
+	if (err)
+	{
+		px_free(buf);
+		px_free(cx);
+		return err;
+	}
+
+	err = px_find_cipher(s_cipher, &cx->cipher);
+	if (err)
+		goto err1;
+
+	if (s_pad != NULL)
+	{
+		if (strcmp(s_pad, "pkcs") == 0)
+			cx->padding = 1;
+		else if (strcmp(s_pad, "none") == 0)
+			cx->padding = 0;
+		else
+			goto err1;
+	}
+	else
+		cx->padding = 1;
+
+	cx->init = combo_init;
+	cx->encrypt = combo_encrypt;
+	cx->decrypt = combo_decrypt;
+	cx->encrypt_len = combo_encrypt_len;
+	cx->decrypt_len = combo_decrypt_len;
+	cx->free = combo_free;
+
+	px_free(buf);
+
+	*res = cx;
+
+	return 0;
+
+err1:
+	if (cx->cipher)
+		px_cipher_free(cx->cipher);
+	px_free(cx);
+	px_free(buf);
+	return PXE_NO_CIPHER;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/px.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h
new file mode 100644
index 0000000..610b7fa
--- /dev/null
+++ b/contrib/pgcrypto/px.h
@@ -0,0 +1,250 @@
+/*
+ * px.h
+ *		Header file for pgcrypto.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/px.h
+ */
+
+#ifndef __PX_H
+#define __PX_H
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+/* keep debug messages? */
+#define PX_DEBUG
+
+/* a way to disable palloc
+ * - useful if compiled into standalone
+ */
+#ifndef PX_OWN_ALLOC
+#define px_alloc(s) palloc(s)
+#define px_realloc(p, s) repalloc(p, s)
+#define px_free(p)	pfree(p)
+#else
+void	   *px_alloc(size_t s);
+void	   *px_realloc(void *p, size_t s);
+void		px_free(void *p);
+#endif
+
+/* max len of 'type' parms */
+#define PX_MAX_NAMELEN		128
+
+/* max salt returned */
+#define PX_MAX_SALT_LEN		128
+
+/*
+ * PX error codes
+ */
+#define PXE_OK						0
+#define PXE_ERR_GENERIC				-1
+#define PXE_NO_HASH					-2
+#define PXE_NO_CIPHER				-3
+#define PXE_NOTBLOCKSIZE			-4
+#define PXE_BAD_OPTION				-5
+#define PXE_BAD_FORMAT				-6
+#define PXE_KEY_TOO_BIG				-7
+#define PXE_CIPHER_INIT				-8
+#define PXE_HASH_UNUSABLE_FOR_HMAC	-9
+#define PXE_DEV_READ_ERROR			-10
+#define PXE_OSSL_RAND_ERROR			-11
+#define PXE_BUG						-12
+#define PXE_ARGUMENT_ERROR			-13
+#define PXE_UNKNOWN_SALT_ALGO		-14
+#define PXE_BAD_SALT_ROUNDS			-15
+#define PXE_MCRYPT_INTERNAL			-16
+#define PXE_NO_RANDOM				-17
+#define PXE_DECRYPT_FAILED			-18
+
+#define PXE_MBUF_SHORT_READ			-50
+
+#define PXE_PGP_CORRUPT_DATA		-100
+#define PXE_PGP_CORRUPT_ARMOR		-101
+#define PXE_PGP_UNSUPPORTED_COMPR	-102
+#define PXE_PGP_UNSUPPORTED_CIPHER	-103
+#define PXE_PGP_UNSUPPORTED_HASH	-104
+#define PXE_PGP_COMPRESSION_ERROR	-105
+#define PXE_PGP_NOT_TEXT			-106
+#define PXE_PGP_UNEXPECTED_PKT		-107
+#define PXE_PGP_NO_BIGNUM			-108
+#define PXE_PGP_MATH_FAILED			-109
+#define PXE_PGP_SHORT_ELGAMAL_KEY	-110
+#define PXE_PGP_RSA_UNSUPPORTED		-111
+#define PXE_PGP_UNKNOWN_PUBALGO		-112
+#define PXE_PGP_WRONG_KEY			-113
+#define PXE_PGP_MULTIPLE_KEYS		-114
+#define PXE_PGP_EXPECT_PUBLIC_KEY	-115
+#define PXE_PGP_EXPECT_SECRET_KEY	-116
+#define PXE_PGP_NOT_V4_KEYPKT		-117
+#define PXE_PGP_KEYPKT_CORRUPT		-118
+#define PXE_PGP_NO_USABLE_KEY		-119
+#define PXE_PGP_NEED_SECRET_PSW		-120
+#define PXE_PGP_BAD_S2K_MODE		-121
+#define PXE_PGP_UNSUPPORTED_PUBALGO -122
+#define PXE_PGP_MULTIPLE_SUBKEYS	-123
+
+
+typedef struct px_digest PX_MD;
+typedef struct px_alias PX_Alias;
+typedef struct px_hmac PX_HMAC;
+typedef struct px_cipher PX_Cipher;
+typedef struct px_combo PX_Combo;
+
+struct px_digest
+{
+	unsigned	(*result_size) (PX_MD *h);
+	unsigned	(*block_size) (PX_MD *h);
+	void		(*reset) (PX_MD *h);
+	void		(*update) (PX_MD *h, const uint8 *data, unsigned dlen);
+	void		(*finish) (PX_MD *h, uint8 *dst);
+	void		(*free) (PX_MD *h);
+	/* private */
+	union
+	{
+		unsigned	code;
+		void	   *ptr;
+	}			p;
+};
+
+struct px_alias
+{
+	char	   *alias;
+	char	   *name;
+};
+
+struct px_hmac
+{
+	unsigned	(*result_size) (PX_HMAC *h);
+	unsigned	(*block_size) (PX_HMAC *h);
+	void		(*reset) (PX_HMAC *h);
+	void		(*update) (PX_HMAC *h, const uint8 *data, unsigned dlen);
+	void		(*finish) (PX_HMAC *h, uint8 *dst);
+	void		(*free) (PX_HMAC *h);
+	void		(*init) (PX_HMAC *h, const uint8 *key, unsigned klen);
+
+	PX_MD	   *md;
+	/* private */
+	struct
+	{
+		uint8	   *ipad;
+		uint8	   *opad;
+	}			p;
+};
+
+struct px_cipher
+{
+	unsigned	(*block_size) (PX_Cipher *c);
+	unsigned	(*key_size) (PX_Cipher *c);		/* max key len */
+	unsigned	(*iv_size) (PX_Cipher *c);
+
+	int			(*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv);
+	int			(*encrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
+	int			(*decrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
+	void		(*free) (PX_Cipher *c);
+	/* private */
+	void	   *ptr;
+	int			pstat;			/* mcrypt uses it */
+};
+
+struct px_combo
+{
+	int			(*init) (PX_Combo *cx, const uint8 *key, unsigned klen,
+									 const uint8 *iv, unsigned ivlen);
+	int			(*encrypt) (PX_Combo *cx, const uint8 *data, unsigned dlen,
+										uint8 *res, unsigned *rlen);
+	int			(*decrypt) (PX_Combo *cx, const uint8 *data, unsigned dlen,
+										uint8 *res, unsigned *rlen);
+	unsigned	(*encrypt_len) (PX_Combo *cx, unsigned dlen);
+	unsigned	(*decrypt_len) (PX_Combo *cx, unsigned dlen);
+	void		(*free) (PX_Combo *cx);
+
+	PX_Cipher  *cipher;
+	unsigned	padding;
+};
+
+int			px_find_digest(const char *name, PX_MD **res);
+int			px_find_hmac(const char *name, PX_HMAC **res);
+int			px_find_cipher(const char *name, PX_Cipher **res);
+int			px_find_combo(const char *name, PX_Combo **res);
+
+int			px_get_random_bytes(uint8 *dst, unsigned count);
+int			px_get_pseudo_random_bytes(uint8 *dst, unsigned count);
+int			px_add_entropy(const uint8 *data, unsigned count);
+
+unsigned	px_acquire_system_randomness(uint8 *dst);
+
+const char *px_strerror(int err);
+
+const char *px_resolve_alias(const PX_Alias *aliases, const char *name);
+
+void		px_set_debug_handler(void (*handler) (const char *));
+
+#ifdef PX_DEBUG
+void		px_debug(const char *fmt, ...)
+	__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+#else
+#define px_debug(...)
+#endif
+
+#define px_md_result_size(md)		(md)->result_size(md)
+#define px_md_block_size(md)		(md)->block_size(md)
+#define px_md_reset(md)			(md)->reset(md)
+#define px_md_update(md, data, dlen)	(md)->update(md, data, dlen)
+#define px_md_finish(md, buf)		(md)->finish(md, buf)
+#define px_md_free(md)			(md)->free(md)
+
+#define px_hmac_result_size(hmac)	(hmac)->result_size(hmac)
+#define px_hmac_block_size(hmac)	(hmac)->block_size(hmac)
+#define px_hmac_reset(hmac)		(hmac)->reset(hmac)
+#define px_hmac_init(hmac, key, klen)	(hmac)->init(hmac, key, klen)
+#define px_hmac_update(hmac, data, dlen) (hmac)->update(hmac, data, dlen)
+#define px_hmac_finish(hmac, buf)	(hmac)->finish(hmac, buf)
+#define px_hmac_free(hmac)		(hmac)->free(hmac)
+
+
+#define px_cipher_key_size(c)		(c)->key_size(c)
+#define px_cipher_block_size(c)		(c)->block_size(c)
+#define px_cipher_iv_size(c)		(c)->iv_size(c)
+#define px_cipher_init(c, k, klen, iv)	(c)->init(c, k, klen, iv)
+#define px_cipher_encrypt(c, data, dlen, res) \
+					(c)->encrypt(c, data, dlen, res)
+#define px_cipher_decrypt(c, data, dlen, res) \
+					(c)->decrypt(c, data, dlen, res)
+#define px_cipher_free(c)		(c)->free(c)
+
+
+#define px_combo_encrypt_len(c, dlen)	(c)->encrypt_len(c, dlen)
+#define px_combo_decrypt_len(c, dlen)	(c)->decrypt_len(c, dlen)
+#define px_combo_init(c, key, klen, iv, ivlen) \
+					(c)->init(c, key, klen, iv, ivlen)
+#define px_combo_encrypt(c, data, dlen, res, rlen) \
+					(c)->encrypt(c, data, dlen, res, rlen)
+#define px_combo_decrypt(c, data, dlen, res, rlen) \
+					(c)->decrypt(c, data, dlen, res, rlen)
+#define px_combo_free(c)		(c)->free(c)
+
+#endif   /* __PX_H */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/random.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/random.c b/contrib/pgcrypto/random.c
new file mode 100644
index 0000000..393a0be
--- /dev/null
+++ b/contrib/pgcrypto/random.c
@@ -0,0 +1,244 @@
+/*
+ * random.c
+ *		Acquire randomness from system.  For seeding RNG.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/random.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+
+/* how many bytes to ask from system random provider */
+#define RND_BYTES  32
+
+/*
+ * Try to read from /dev/urandom or /dev/random on these OS'es.
+ *
+ * The list can be pretty liberal, as the device not existing
+ * is expected event.
+ */
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
+	|| defined(__NetBSD__) || defined(__DragonFly__) \
+	|| defined(__darwin__) || defined(__SOLARIS__) \
+	|| defined(__hpux) || defined(__HPUX__) \
+	|| defined(__CYGWIN__) || defined(_AIX)
+
+#define TRY_DEV_RANDOM
+
+#include <fcntl.h>
+#include <unistd.h>
+
+static int
+safe_read(int fd, void *buf, size_t count)
+{
+	int			done = 0;
+	char	   *p = buf;
+	int			res;
+
+	while (count)
+	{
+		res = read(fd, p, count);
+		if (res <= 0)
+		{
+			if (errno == EINTR)
+				continue;
+			return PXE_DEV_READ_ERROR;
+		}
+		p += res;
+		done += res;
+		count -= res;
+	}
+	return done;
+}
+
+static uint8 *
+try_dev_random(uint8 *dst)
+{
+	int			fd;
+	int			res;
+
+	fd = open("/dev/urandom", O_RDONLY, 0);
+	if (fd == -1)
+	{
+		fd = open("/dev/random", O_RDONLY, 0);
+		if (fd == -1)
+			return dst;
+	}
+	res = safe_read(fd, dst, RND_BYTES);
+	close(fd);
+	if (res > 0)
+		dst += res;
+	return dst;
+}
+#endif
+
+/*
+ * Try to find randomness on Windows
+ */
+#ifdef WIN32
+
+#define TRY_WIN32_GENRAND
+#define TRY_WIN32_PERFC
+
+#include <windows.h>
+#include <wincrypt.h>
+
+/*
+ * this function is from libtomcrypt
+ *
+ * try to use Microsoft crypto API
+ */
+static uint8 *
+try_win32_genrand(uint8 *dst)
+{
+	int			res;
+	HCRYPTPROV	h = 0;
+
+	res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
+							  (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
+	if (!res)
+		res = CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL,
+			   CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET);
+	if (!res)
+		return dst;
+
+	res = CryptGenRandom(h, RND_BYTES, dst);
+	if (res == TRUE)
+		dst += RND_BYTES;
+
+	CryptReleaseContext(h, 0);
+	return dst;
+}
+
+static uint8 *
+try_win32_perfc(uint8 *dst)
+{
+	int			res;
+	LARGE_INTEGER time;
+
+	res = QueryPerformanceCounter(&time);
+	if (!res)
+		return dst;
+
+	memcpy(dst, &time, sizeof(time));
+	return dst + sizeof(time);
+}
+#endif   /* WIN32 */
+
+
+/*
+ * If we are not on Windows, then hopefully we are
+ * on a unix-like system.  Use the usual suspects
+ * for randomness.
+ */
+#ifndef WIN32
+
+#define TRY_UNIXSTD
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+/*
+ * Everything here is predictible, only needs some patience.
+ *
+ * But there is a chance that the system-specific functions
+ * did not work.  So keep faith and try to slow the attacker down.
+ */
+static uint8 *
+try_unix_std(uint8 *dst)
+{
+	pid_t		pid;
+	int			x;
+	PX_MD	   *md;
+	struct timeval tv;
+	int			res;
+
+	/* process id */
+	pid = getpid();
+	memcpy(dst, (uint8 *) &pid, sizeof(pid));
+	dst += sizeof(pid);
+
+	/* time */
+	gettimeofday(&tv, NULL);
+	memcpy(dst, (uint8 *) &tv, sizeof(tv));
+	dst += sizeof(tv);
+
+	/* pointless, but should not hurt */
+	x = random();
+	memcpy(dst, (uint8 *) &x, sizeof(x));
+	dst += sizeof(x);
+
+	/* let's be desperate */
+	res = px_find_digest("sha1", &md);
+	if (res >= 0)
+	{
+		uint8	   *ptr;
+		uint8		stack[8192];
+		int			alloc = 32 * 1024;
+
+		px_md_update(md, stack, sizeof(stack));
+		ptr = px_alloc(alloc);
+		px_md_update(md, ptr, alloc);
+		px_free(ptr);
+
+		px_md_finish(md, dst);
+		px_md_free(md);
+
+		dst += 20;
+	}
+
+	return dst;
+}
+#endif
+
+/*
+ * try to extract some randomness for initial seeding
+ *
+ * dst should have room for 1024 bytes.
+ */
+unsigned
+px_acquire_system_randomness(uint8 *dst)
+{
+	uint8	   *p = dst;
+
+#ifdef TRY_DEV_RANDOM
+	p = try_dev_random(p);
+#endif
+#ifdef TRY_WIN32_GENRAND
+	p = try_win32_genrand(p);
+#endif
+#ifdef TRY_WIN32_PERFC
+	p = try_win32_perfc(p);
+#endif
+#ifdef TRY_UNIXSTD
+	p = try_unix_std(p);
+#endif
+	return p - dst;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/rijndael.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/rijndael.c b/contrib/pgcrypto/rijndael.c
new file mode 100644
index 0000000..5651d03
--- /dev/null
+++ b/contrib/pgcrypto/rijndael.c
@@ -0,0 +1,677 @@
+/*	$OpenBSD: rijndael.c,v 1.6 2000/12/09 18:51:34 markus Exp $ */
+
+/* contrib/pgcrypto/rijndael.c */
+
+/* This is an independent implementation of the encryption algorithm:	*/
+/*																		*/
+/*		   RIJNDAEL by Joan Daemen and Vincent Rijmen					*/
+/*																		*/
+/* which is a candidate algorithm in the Advanced Encryption Standard	*/
+/* programme of the US National Institute of Standards and Technology.	*/
+/*																		*/
+/* Copyright in this implementation is held by Dr B R Gladman but I		*/
+/* hereby give permission for its free direct or derivative use subject */
+/* to acknowledgment of its origin and compliance with any conditions	*/
+/* that the originators of the algorithm place on its exploitation.		*/
+/*																		*/
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999		*/
+
+/* Timing data for Rijndael (rijndael.c)
+
+Algorithm: rijndael (rijndael.c)
+
+128 bit key:
+Key Setup:	  305/1389 cycles (encrypt/decrypt)
+Encrypt:	   374 cycles =    68.4 mbits/sec
+Decrypt:	   352 cycles =    72.7 mbits/sec
+Mean:		   363 cycles =    70.5 mbits/sec
+
+192 bit key:
+Key Setup:	  277/1595 cycles (encrypt/decrypt)
+Encrypt:	   439 cycles =    58.3 mbits/sec
+Decrypt:	   425 cycles =    60.2 mbits/sec
+Mean:		   432 cycles =    59.3 mbits/sec
+
+256 bit key:
+Key Setup:	  374/1960 cycles (encrypt/decrypt)
+Encrypt:	   502 cycles =    51.0 mbits/sec
+Decrypt:	   498 cycles =    51.4 mbits/sec
+Mean:		   500 cycles =    51.2 mbits/sec
+
+*/
+
+#include "postgres.h"
+
+#include <sys/param.h>
+
+#include "px.h"
+#include "rijndael.h"
+
+#define PRE_CALC_TABLES
+#define LARGE_TABLES
+
+static void gen_tabs(void);
+
+/* 3. Basic macros for speeding up generic operations				*/
+
+/* Circular rotate of 32 bit values									*/
+
+#define rotr(x,n)	(((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
+#define rotl(x,n)	(((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
+
+/* Invert byte order in a 32 bit variable							*/
+
+#define bswap(x)	((rotl((x), 8) & 0x00ff00ff) | (rotr((x), 8) & 0xff00ff00))
+
+/* Extract byte from a 32 bit quantity (little endian notation)		*/
+
+#define byte(x,n)	((u1byte)((x) >> (8 * (n))))
+
+#ifdef WORDS_BIGENDIAN
+#define io_swap(x)	bswap(x)
+#else
+#define io_swap(x)	(x)
+#endif
+
+#ifdef PRINT_TABS
+#undef PRE_CALC_TABLES
+#endif
+
+#ifdef PRE_CALC_TABLES
+
+#include "rijndael.tbl"
+#define tab_gen		1
+#else							/* !PRE_CALC_TABLES */
+
+static u1byte pow_tab[256];
+static u1byte log_tab[256];
+static u1byte sbx_tab[256];
+static u1byte isb_tab[256];
+static u4byte rco_tab[10];
+static u4byte ft_tab[4][256];
+static u4byte it_tab[4][256];
+
+#ifdef	LARGE_TABLES
+static u4byte fl_tab[4][256];
+static u4byte il_tab[4][256];
+#endif
+
+static u4byte tab_gen = 0;
+#endif   /* !PRE_CALC_TABLES */
+
+#define ff_mult(a,b)	((a) && (b) ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
+
+#define f_rn(bo, bi, n, k)								\
+	(bo)[n] =  ft_tab[0][byte((bi)[n],0)] ^				\
+			 ft_tab[1][byte((bi)[((n) + 1) & 3],1)] ^	\
+			 ft_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 ft_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n))
+
+#define i_rn(bo, bi, n, k)							\
+	(bo)[n] =  it_tab[0][byte((bi)[n],0)] ^				\
+			 it_tab[1][byte((bi)[((n) + 3) & 3],1)] ^	\
+			 it_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 it_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n))
+
+#ifdef LARGE_TABLES
+
+#define ls_box(x)				 \
+	( fl_tab[0][byte(x, 0)] ^	 \
+	  fl_tab[1][byte(x, 1)] ^	 \
+	  fl_tab[2][byte(x, 2)] ^	 \
+	  fl_tab[3][byte(x, 3)] )
+
+#define f_rl(bo, bi, n, k)								\
+	(bo)[n] =  fl_tab[0][byte((bi)[n],0)] ^				\
+			 fl_tab[1][byte((bi)[((n) + 1) & 3],1)] ^	\
+			 fl_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 fl_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n))
+
+#define i_rl(bo, bi, n, k)								\
+	(bo)[n] =  il_tab[0][byte((bi)[n],0)] ^				\
+			 il_tab[1][byte((bi)[((n) + 3) & 3],1)] ^	\
+			 il_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 il_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n))
+#else
+
+#define ls_box(x)							 \
+	((u4byte)sbx_tab[byte(x, 0)] <<  0) ^	 \
+	((u4byte)sbx_tab[byte(x, 1)] <<  8) ^	 \
+	((u4byte)sbx_tab[byte(x, 2)] << 16) ^	 \
+	((u4byte)sbx_tab[byte(x, 3)] << 24)
+
+#define f_rl(bo, bi, n, k)											\
+	(bo)[n] = (u4byte)sbx_tab[byte((bi)[n],0)] ^					\
+		rotl(((u4byte)sbx_tab[byte((bi)[((n) + 1) & 3],1)]),  8) ^	\
+		rotl(((u4byte)sbx_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^	\
+		rotl(((u4byte)sbx_tab[byte((bi)[((n) + 3) & 3],3)]), 24) ^ *((k) + (n))
+
+#define i_rl(bo, bi, n, k)											\
+	(bo)[n] = (u4byte)isb_tab[byte((bi)[n],0)] ^					\
+		rotl(((u4byte)isb_tab[byte((bi)[((n) + 3) & 3],1)]),  8) ^	\
+		rotl(((u4byte)isb_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^	\
+		rotl(((u4byte)isb_tab[byte((bi)[((n) + 1) & 3],3)]), 24) ^ *((k) + (n))
+#endif
+
+static void
+gen_tabs(void)
+{
+#ifndef PRE_CALC_TABLES
+	u4byte		i,
+				t;
+	u1byte		p,
+				q;
+
+	/* log and power tables for GF(2**8) finite field with	*/
+	/* 0x11b as modular polynomial - the simplest prmitive	*/
+	/* root is 0x11, used here to generate the tables		*/
+
+	for (i = 0, p = 1; i < 256; ++i)
+	{
+		pow_tab[i] = (u1byte) p;
+		log_tab[p] = (u1byte) i;
+
+		p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+	p = 1;
+
+	for (i = 0; i < 10; ++i)
+	{
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
+	}
+
+	/* note that the affine byte transformation matrix in	*/
+	/* rijndael specification is in big endian format with	*/
+	/* bit 0 as the most significant bit. In the remainder	*/
+	/* of the specification the bits are numbered from the	*/
+	/* least significant end of a byte.						*/
+
+	for (i = 0; i < 256; ++i)
+	{
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = p;
+		q = (q >> 7) | (q << 1);
+		p ^= q;
+		q = (q >> 7) | (q << 1);
+		p ^= q;
+		q = (q >> 7) | (q << 1);
+		p ^= q;
+		q = (q >> 7) | (q << 1);
+		p ^= q ^ 0x63;
+		sbx_tab[i] = (u1byte) p;
+		isb_tab[p] = (u1byte) i;
+	}
+
+	for (i = 0; i < 256; ++i)
+	{
+		p = sbx_tab[i];
+
+#ifdef	LARGE_TABLES
+
+		t = p;
+		fl_tab[0][i] = t;
+		fl_tab[1][i] = rotl(t, 8);
+		fl_tab[2][i] = rotl(t, 16);
+		fl_tab[3][i] = rotl(t, 24);
+#endif
+		t = ((u4byte) ff_mult(2, p)) |
+			((u4byte) p << 8) |
+			((u4byte) p << 16) |
+			((u4byte) ff_mult(3, p) << 24);
+
+		ft_tab[0][i] = t;
+		ft_tab[1][i] = rotl(t, 8);
+		ft_tab[2][i] = rotl(t, 16);
+		ft_tab[3][i] = rotl(t, 24);
+
+		p = isb_tab[i];
+
+#ifdef	LARGE_TABLES
+
+		t = p;
+		il_tab[0][i] = t;
+		il_tab[1][i] = rotl(t, 8);
+		il_tab[2][i] = rotl(t, 16);
+		il_tab[3][i] = rotl(t, 24);
+#endif
+		t = ((u4byte) ff_mult(14, p)) |
+			((u4byte) ff_mult(9, p) << 8) |
+			((u4byte) ff_mult(13, p) << 16) |
+			((u4byte) ff_mult(11, p) << 24);
+
+		it_tab[0][i] = t;
+		it_tab[1][i] = rotl(t, 8);
+		it_tab[2][i] = rotl(t, 16);
+		it_tab[3][i] = rotl(t, 24);
+	}
+
+	tab_gen = 1;
+#endif   /* !PRE_CALC_TABLES */
+}
+
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y,x)		\
+do { \
+	u	= star_x(x);		\
+	v	= star_x(u);		\
+	w	= star_x(v);		\
+	t	= w ^ (x);			\
+   (y)	= u ^ v ^ w;		\
+   (y) ^= rotr(u ^ t,  8) ^ \
+		  rotr(v ^ t, 16) ^ \
+		  rotr(t,24);		\
+} while (0)
+
+/* initialise the key schedule from the user supplied key	*/
+
+#define loop4(i)									\
+do {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];		   \
+	t ^= e_key[4 * i];	   e_key[4 * i + 4] = t;	\
+	t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t;	\
+	t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t;	\
+	t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t;	\
+} while (0)
+
+#define loop6(i)									\
+do {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];		   \
+	t ^= e_key[6 * (i)];	   e_key[6 * (i) + 6] = t;	\
+	t ^= e_key[6 * (i) + 1]; e_key[6 * (i) + 7] = t;	\
+	t ^= e_key[6 * (i) + 2]; e_key[6 * (i) + 8] = t;	\
+	t ^= e_key[6 * (i) + 3]; e_key[6 * (i) + 9] = t;	\
+	t ^= e_key[6 * (i) + 4]; e_key[6 * (i) + 10] = t;	\
+	t ^= e_key[6 * (i) + 5]; e_key[6 * (i) + 11] = t;	\
+} while (0)
+
+#define loop8(i)									\
+do {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];		   \
+	t ^= e_key[8 * (i)];	 e_key[8 * (i) + 8] = t;	\
+	t ^= e_key[8 * (i) + 1]; e_key[8 * (i) + 9] = t;	\
+	t ^= e_key[8 * (i) + 2]; e_key[8 * (i) + 10] = t;	\
+	t ^= e_key[8 * (i) + 3]; e_key[8 * (i) + 11] = t;	\
+	t  = e_key[8 * (i) + 4] ^ ls_box(t);				\
+	e_key[8 * (i) + 12] = t;							\
+	t ^= e_key[8 * (i) + 5]; e_key[8 * (i) + 13] = t;	\
+	t ^= e_key[8 * (i) + 6]; e_key[8 * (i) + 14] = t;	\
+	t ^= e_key[8 * (i) + 7]; e_key[8 * (i) + 15] = t;	\
+} while (0)
+
+rijndael_ctx *
+rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len,
+				 int encrypt)
+{
+	u4byte		i,
+				t,
+				u,
+				v,
+				w;
+	u4byte	   *e_key = ctx->e_key;
+	u4byte	   *d_key = ctx->d_key;
+
+	ctx->decrypt = !encrypt;
+
+	if (!tab_gen)
+		gen_tabs();
+
+	ctx->k_len = (key_len + 31) / 32;
+
+	e_key[0] = io_swap(in_key[0]);
+	e_key[1] = io_swap(in_key[1]);
+	e_key[2] = io_swap(in_key[2]);
+	e_key[3] = io_swap(in_key[3]);
+
+	switch (ctx->k_len)
+	{
+		case 4:
+			t = e_key[3];
+			for (i = 0; i < 10; ++i)
+				loop4(i);
+			break;
+
+		case 6:
+			e_key[4] = io_swap(in_key[4]);
+			t = e_key[5] = io_swap(in_key[5]);
+			for (i = 0; i < 8; ++i)
+				loop6(i);
+			break;
+
+		case 8:
+			e_key[4] = io_swap(in_key[4]);
+			e_key[5] = io_swap(in_key[5]);
+			e_key[6] = io_swap(in_key[6]);
+			t = e_key[7] = io_swap(in_key[7]);
+			for (i = 0; i < 7; ++i)
+				loop8(i);
+			break;
+	}
+
+	if (!encrypt)
+	{
+		d_key[0] = e_key[0];
+		d_key[1] = e_key[1];
+		d_key[2] = e_key[2];
+		d_key[3] = e_key[3];
+
+		for (i = 4; i < 4 * ctx->k_len + 24; ++i)
+			imix_col(d_key[i], e_key[i]);
+	}
+
+	return ctx;
+}
+
+/* encrypt a block of text	*/
+
+#define f_nround(bo, bi, k) \
+do { \
+	f_rn(bo, bi, 0, k);		\
+	f_rn(bo, bi, 1, k);		\
+	f_rn(bo, bi, 2, k);		\
+	f_rn(bo, bi, 3, k);		\
+	k += 4;					\
+} while (0)
+
+#define f_lround(bo, bi, k) \
+do { \
+	f_rl(bo, bi, 0, k);		\
+	f_rl(bo, bi, 1, k);		\
+	f_rl(bo, bi, 2, k);		\
+	f_rl(bo, bi, 3, k);		\
+} while (0)
+
+void
+rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
+{
+	u4byte		k_len = ctx->k_len;
+	u4byte	   *e_key = ctx->e_key;
+	u4byte		b0[4],
+				b1[4],
+			   *kp;
+
+	b0[0] = io_swap(in_blk[0]) ^ e_key[0];
+	b0[1] = io_swap(in_blk[1]) ^ e_key[1];
+	b0[2] = io_swap(in_blk[2]) ^ e_key[2];
+	b0[3] = io_swap(in_blk[3]) ^ e_key[3];
+
+	kp = e_key + 4;
+
+	if (k_len > 6)
+	{
+		f_nround(b1, b0, kp);
+		f_nround(b0, b1, kp);
+	}
+
+	if (k_len > 4)
+	{
+		f_nround(b1, b0, kp);
+		f_nround(b0, b1, kp);
+	}
+
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_lround(b0, b1, kp);
+
+	out_blk[0] = io_swap(b0[0]);
+	out_blk[1] = io_swap(b0[1]);
+	out_blk[2] = io_swap(b0[2]);
+	out_blk[3] = io_swap(b0[3]);
+}
+
+/* decrypt a block of text	*/
+
+#define i_nround(bo, bi, k) \
+do { \
+	i_rn(bo, bi, 0, k);		\
+	i_rn(bo, bi, 1, k);		\
+	i_rn(bo, bi, 2, k);		\
+	i_rn(bo, bi, 3, k);		\
+	k -= 4;					\
+} while (0)
+
+#define i_lround(bo, bi, k) \
+do { \
+	i_rl(bo, bi, 0, k);		\
+	i_rl(bo, bi, 1, k);		\
+	i_rl(bo, bi, 2, k);		\
+	i_rl(bo, bi, 3, k);		\
+} while (0)
+
+void
+rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
+{
+	u4byte		b0[4],
+				b1[4],
+			   *kp;
+	u4byte		k_len = ctx->k_len;
+	u4byte	   *e_key = ctx->e_key;
+	u4byte	   *d_key = ctx->d_key;
+
+	b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24];
+	b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25];
+	b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26];
+	b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27];
+
+	kp = d_key + 4 * (k_len + 5);
+
+	if (k_len > 6)
+	{
+		i_nround(b1, b0, kp);
+		i_nround(b0, b1, kp);
+	}
+
+	if (k_len > 4)
+	{
+		i_nround(b1, b0, kp);
+		i_nround(b0, b1, kp);
+	}
+
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_lround(b0, b1, kp);
+
+	out_blk[0] = io_swap(b0[0]);
+	out_blk[1] = io_swap(b0[1]);
+	out_blk[2] = io_swap(b0[2]);
+	out_blk[3] = io_swap(b0[3]);
+}
+
+/*
+ * conventional interface
+ *
+ * ATM it hopes all data is 4-byte aligned - which
+ * should be true for PX.  -marko
+ */
+
+void
+aes_set_key(rijndael_ctx *ctx, const uint8 *key, unsigned keybits, int enc)
+{
+	uint32	   *k;
+
+	k = (uint32 *) key;
+	rijndael_set_key(ctx, k, keybits, enc);
+}
+
+void
+aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
+{
+	unsigned	bs = 16;
+	uint32	   *d;
+
+	while (len >= bs)
+	{
+		d = (uint32 *) data;
+		rijndael_encrypt(ctx, d, d);
+
+		len -= bs;
+		data += bs;
+	}
+}
+
+void
+aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
+{
+	unsigned	bs = 16;
+	uint32	   *d;
+
+	while (len >= bs)
+	{
+		d = (uint32 *) data;
+		rijndael_decrypt(ctx, d, d);
+
+		len -= bs;
+		data += bs;
+	}
+}
+
+void
+aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
+{
+	uint32	   *iv = (uint32 *) iva;
+	uint32	   *d = (uint32 *) data;
+	unsigned	bs = 16;
+
+	while (len >= bs)
+	{
+		d[0] ^= iv[0];
+		d[1] ^= iv[1];
+		d[2] ^= iv[2];
+		d[3] ^= iv[3];
+
+		rijndael_encrypt(ctx, d, d);
+
+		iv = d;
+		d += bs / 4;
+		len -= bs;
+	}
+}
+
+void
+aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
+{
+	uint32	   *d = (uint32 *) data;
+	unsigned	bs = 16;
+	uint32		buf[4],
+				iv[4];
+
+	memcpy(iv, iva, bs);
+	while (len >= bs)
+	{
+		buf[0] = d[0];
+		buf[1] = d[1];
+		buf[2] = d[2];
+		buf[3] = d[3];
+
+		rijndael_decrypt(ctx, buf, d);
+
+		d[0] ^= iv[0];
+		d[1] ^= iv[1];
+		d[2] ^= iv[2];
+		d[3] ^= iv[3];
+
+		iv[0] = buf[0];
+		iv[1] = buf[1];
+		iv[2] = buf[2];
+		iv[3] = buf[3];
+		d += 4;
+		len -= bs;
+	}
+}
+
+/*
+ * pre-calculate tables.
+ *
+ * On i386 lifts 17k from .bss to .rodata
+ * and avoids 1k code and setup time.
+ *	  -marko
+ */
+#ifdef PRINT_TABS
+
+static void
+show256u8(char *name, uint8 *data)
+{
+	int			i;
+
+	printf("static const u1byte  %s[256] = {\n  ", name);
+	for (i = 0; i < 256;)
+	{
+		printf("%u", pow_tab[i++]);
+		if (i < 256)
+			printf(i % 16 ? ", " : ",\n  ");
+	}
+	printf("\n};\n\n");
+}
+
+
+static void
+show4x256u32(char *name, uint32 data[4][256])
+{
+	int			i,
+				j;
+
+	printf("static const u4byte  %s[4][256] = {\n{\n  ", name);
+	for (i = 0; i < 4; i++)
+	{
+		for (j = 0; j < 256;)
+		{
+			printf("0x%08x", data[i][j]);
+			j++;
+			if (j < 256)
+				printf(j % 4 ? ", " : ",\n  ");
+		}
+		printf(i < 3 ? "\n}, {\n  " : "\n}\n");
+	}
+	printf("};\n\n");
+}
+
+int
+main()
+{
+	int			i;
+	char	   *hdr = "/* Generated by rijndael.c */\n\n";
+
+	gen_tabs();
+
+	printf(hdr);
+	show256u8("pow_tab", pow_tab);
+	show256u8("log_tab", log_tab);
+	show256u8("sbx_tab", sbx_tab);
+	show256u8("isb_tab", isb_tab);
+
+	show4x256u32("ft_tab", ft_tab);
+	show4x256u32("it_tab", it_tab);
+#ifdef LARGE_TABLES
+	show4x256u32("fl_tab", fl_tab);
+	show4x256u32("il_tab", il_tab);
+#endif
+	printf("static const u4byte rco_tab[10] = {\n  ");
+	for (i = 0; i < 10; i++)
+	{
+		printf("0x%08x", rco_tab[i]);
+		if (i < 9)
+			printf(", ");
+		if (i == 4)
+			printf("\n  ");
+	}
+	printf("\n};\n\n");
+	return 0;
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/rijndael.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/rijndael.h b/contrib/pgcrypto/rijndael.h
new file mode 100644
index 0000000..fb30e46
--- /dev/null
+++ b/contrib/pgcrypto/rijndael.h
@@ -0,0 +1,60 @@
+/*
+ * contrib/pgcrypto/rijndael.h
+ *
+ *	$OpenBSD: rijndael.h,v 1.3 2001/05/09 23:01:32 markus Exp $ */
+
+/* This is an independent implementation of the encryption algorithm:	*/
+/*																		*/
+/*		   RIJNDAEL by Joan Daemen and Vincent Rijmen					*/
+/*																		*/
+/* which is a candidate algorithm in the Advanced Encryption Standard	*/
+/* programme of the US National Institute of Standards and Technology.	*/
+/*																		*/
+/* Copyright in this implementation is held by Dr B R Gladman but I		*/
+/* hereby give permission for its free direct or derivative use subject */
+/* to acknowledgment of its origin and compliance with any conditions	*/
+/* that the originators of the algorithm place on its exploitation.		*/
+/*																		*/
+/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999		*/
+
+#ifndef _RIJNDAEL_H_
+#define _RIJNDAEL_H_
+
+/* 1. Standard types for AES cryptography source code				*/
+
+typedef uint8 u1byte;			/* an 8 bit unsigned character type */
+typedef uint16 u2byte;			/* a 16 bit unsigned integer type	*/
+typedef uint32 u4byte;			/* a 32 bit unsigned integer type	*/
+
+typedef int8 s1byte;			/* an 8 bit signed character type	*/
+typedef int16 s2byte;			/* a 16 bit signed integer type		*/
+typedef int32 s4byte;			/* a 32 bit signed integer type		*/
+
+typedef struct _rijndael_ctx
+{
+	u4byte		k_len;
+	int			decrypt;
+	u4byte		e_key[64];
+	u4byte		d_key[64];
+} rijndael_ctx;
+
+
+/* 2. Standard interface for AES cryptographic routines				*/
+
+/* These are all based on 32 bit unsigned values and will therefore */
+/* require endian conversions for big-endian architectures			*/
+
+rijndael_ctx *
+			rijndael_set_key(rijndael_ctx *, const u4byte *, const u4byte, int);
+void		rijndael_encrypt(rijndael_ctx *, const u4byte *, u4byte *);
+void		rijndael_decrypt(rijndael_ctx *, const u4byte *, u4byte *);
+
+/* conventional interface */
+
+void		aes_set_key(rijndael_ctx *ctx, const uint8 *key, unsigned keybits, int enc);
+void		aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len);
+void		aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len);
+void		aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len);
+void		aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len);
+
+#endif   /* _RIJNDAEL_H_ */



[12/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto b/contrib/pgcrypto
deleted file mode 120000
index a40c453..0000000
--- a/contrib/pgcrypto
+++ /dev/null
@@ -1 +0,0 @@
-../depends/thirdparty/postgres/contrib/pgcrypto
\ No newline at end of file
diff --git a/contrib/pgcrypto/.gitignore b/contrib/pgcrypto/.gitignore
new file mode 100644
index 0000000..dc533ee
--- /dev/null
+++ b/contrib/pgcrypto/.gitignore
@@ -0,0 +1,5 @@
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
+pgcrypto.sql
diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile
new file mode 100644
index 0000000..b7cb3a6
--- /dev/null
+++ b/contrib/pgcrypto/Makefile
@@ -0,0 +1,66 @@
+# contrib/pgcrypto/Makefile
+
+INT_SRCS = md5.c sha1.c sha2.c internal.c internal-sha2.c blf.c rijndael.c \
+		fortuna.c random.c pgp-mpi-internal.c imath.c
+INT_TESTS = sha2
+
+OSSL_SRCS = openssl.c pgp-mpi-openssl.c
+OSSL_TESTS = sha2 des 3des cast5
+
+ZLIB_TST = pgp-compression
+ZLIB_OFF_TST = pgp-zlib-DISABLED
+
+CF_SRCS = $(if $(subst no,,$(with_openssl)), $(OSSL_SRCS), $(INT_SRCS))
+CF_TESTS = $(if $(subst no,,$(with_openssl)), $(OSSL_TESTS), $(INT_TESTS))
+CF_PGP_TESTS = $(if $(subst no,,$(with_zlib)), $(ZLIB_TST), $(ZLIB_OFF_TST))
+
+SRCS		= pgcrypto.c px.c px-hmac.c px-crypt.c \
+		crypt-gensalt.c crypt-blowfish.c crypt-des.c \
+		crypt-md5.c $(CF_SRCS) \
+		mbuf.c pgp.c pgp-armor.c pgp-cfb.c pgp-compress.c \
+		pgp-decrypt.c pgp-encrypt.c pgp-info.c pgp-mpi.c \
+		pgp-pubdec.c pgp-pubenc.c pgp-pubkey.c pgp-s2k.c \
+		pgp-pgsql.c
+
+MODULE_big	= pgcrypto
+OBJS		= $(SRCS:.c=.o)
+
+EXTENSION = pgcrypto
+DATA_built  = pgcrypto.sql
+#DATA = pgcrypto--1.0.sql pgcrypto--unpackaged--1.0.sql
+DATA = uninstall_pgcrypto.sql
+
+REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
+	$(CF_TESTS) \
+	crypt-des crypt-md5 crypt-blowfish crypt-xdes \
+	pgp-armor pgp-decrypt pgp-encrypt $(CF_PGP_TESTS) \
+	pgp-pubkey-decrypt pgp-pubkey-encrypt pgp-info
+
+EXTRA_CLEAN = gen-rtab
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = contrib/pgcrypto
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
+
+# Add libraries that pgcrypto depends (or might depend) on into the
+# shared library link.  (The order in which you list them here doesn't
+# matter.)
+SHLIB_LINK += $(filter -lcrypto -lz, $(LIBS))
+ifeq ($(PORTNAME), win32)
+SHLIB_LINK += $(filter -leay32, $(LIBS))
+# those must be at the end
+SHLIB_LINK += -lwsock32 -lws2_32
+endif
+
+rijndael.o: rijndael.tbl
+
+rijndael.tbl:
+	$(CC) $(CPPFLAGS) $(CFLAGS) -DPRINT_TABS rijndael.c -o gen-rtab
+	./gen-rtab > rijndael.tbl
diff --git a/contrib/pgcrypto/blf.c b/contrib/pgcrypto/blf.c
new file mode 100644
index 0000000..f8a2c63
--- /dev/null
+++ b/contrib/pgcrypto/blf.c
@@ -0,0 +1,499 @@
+/*
+ * Butchered version of sshblowf.c from putty-0.59.
+ *
+ * contrib/pgcrypto/blf.c
+ */
+
+/*
+ * PuTTY is copyright 1997-2007 Simon Tatham.
+ *
+ * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+ * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+ * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
+ * Kuhn, and CORE SDI S.A.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Blowfish implementation for PuTTY.
+ *
+ * Coded from scratch from the algorithm description.
+ */
+
+#include "postgres.h"
+#include "blf.h"
+
+#define GET_32BIT_MSB_FIRST(p) ( \
+	((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3]) )
+
+#define PUT_32BIT_MSB_FIRST(p, v) do { \
+	(p)[0] = v >> 24; \
+	(p)[1] = v >> 16; \
+	(p)[2] = v >> 8; \
+	(p)[3] = v; \
+} while (0)
+
+/*
+ * The Blowfish init data: hex digits of the fractional part of pi.
+ * (ie pi as a hex fraction is 3.243F6A8885A308D3...)
+ */
+static const uint32 parray[] = {
+	0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
+	0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
+	0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B,
+};
+
+static const uint32 sbox0[] = {
+	0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
+	0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
+	0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
+	0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
+	0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
+	0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
+	0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6,
+	0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
+	0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
+	0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
+	0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1,
+	0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
+	0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
+	0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
+	0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
+	0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
+	0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
+	0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
+	0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B,
+	0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
+	0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
+	0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
+	0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A,
+	0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
+	0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760,
+	0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
+	0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
+	0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
+	0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33,
+	0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
+	0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0,
+	0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
+	0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
+	0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
+	0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705,
+	0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
+	0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E,
+	0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
+	0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
+	0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
+	0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F,
+	0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
+	0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A,
+};
+
+static const uint32 sbox1[] = {
+	0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
+	0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
+	0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
+	0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
+	0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
+	0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
+	0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D,
+	0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
+	0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
+	0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
+	0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908,
+	0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
+	0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124,
+	0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
+	0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
+	0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
+	0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B,
+	0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
+	0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA,
+	0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
+	0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
+	0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
+	0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5,
+	0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
+	0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96,
+	0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
+	0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
+	0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
+	0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77,
+	0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
+	0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054,
+	0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
+	0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
+	0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
+	0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646,
+	0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
+	0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA,
+	0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
+	0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
+	0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
+	0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD,
+	0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
+	0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7,
+};
+
+static const uint32 sbox2[] = {
+	0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7,
+	0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
+	0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
+	0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
+	0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4,
+	0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
+	0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC,
+	0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
+	0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
+	0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
+	0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58,
+	0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
+	0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22,
+	0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
+	0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
+	0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
+	0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99,
+	0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
+	0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74,
+	0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
+	0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
+	0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
+	0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979,
+	0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
+	0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA,
+	0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
+	0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
+	0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
+	0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24,
+	0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
+	0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84,
+	0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
+	0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
+	0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
+	0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE,
+	0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
+	0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0,
+	0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
+	0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
+	0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
+	0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8,
+	0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
+	0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0,
+};
+
+static const uint32 sbox3[] = {
+	0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742,
+	0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
+	0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
+	0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
+	0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A,
+	0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
+	0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1,
+	0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
+	0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
+	0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
+	0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6,
+	0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
+	0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA,
+	0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
+	0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
+	0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
+	0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE,
+	0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
+	0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD,
+	0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
+	0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
+	0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
+	0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC,
+	0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
+	0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC,
+	0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
+	0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
+	0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
+	0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A,
+	0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
+	0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B,
+	0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
+	0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
+	0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
+	0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623,
+	0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
+	0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A,
+	0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
+	0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
+	0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
+	0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C,
+	0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
+	0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6,
+};
+
+#define Fprime(a,b,c,d) ( ( (S0[a] + S1[b]) ^ S2[c] ) + S3[d] )
+#define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) )
+#define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t )
+
+static void
+blowfish_encrypt(uint32 xL, uint32 xR, uint32 *output,
+				 BlowfishContext *ctx)
+{
+	uint32	   *S0 = ctx->S0;
+	uint32	   *S1 = ctx->S1;
+	uint32	   *S2 = ctx->S2;
+	uint32	   *S3 = ctx->S3;
+	uint32	   *P = ctx->P;
+	uint32		t;
+
+	ROUND(0);
+	ROUND(1);
+	ROUND(2);
+	ROUND(3);
+	ROUND(4);
+	ROUND(5);
+	ROUND(6);
+	ROUND(7);
+	ROUND(8);
+	ROUND(9);
+	ROUND(10);
+	ROUND(11);
+	ROUND(12);
+	ROUND(13);
+	ROUND(14);
+	ROUND(15);
+	xL ^= P[16];
+	xR ^= P[17];
+
+	output[0] = xR;
+	output[1] = xL;
+}
+
+static void
+blowfish_decrypt(uint32 xL, uint32 xR, uint32 *output,
+				 BlowfishContext *ctx)
+{
+	uint32	   *S0 = ctx->S0;
+	uint32	   *S1 = ctx->S1;
+	uint32	   *S2 = ctx->S2;
+	uint32	   *S3 = ctx->S3;
+	uint32	   *P = ctx->P;
+	uint32		t;
+
+	ROUND(17);
+	ROUND(16);
+	ROUND(15);
+	ROUND(14);
+	ROUND(13);
+	ROUND(12);
+	ROUND(11);
+	ROUND(10);
+	ROUND(9);
+	ROUND(8);
+	ROUND(7);
+	ROUND(6);
+	ROUND(5);
+	ROUND(4);
+	ROUND(3);
+	ROUND(2);
+	xL ^= P[1];
+	xR ^= P[0];
+
+	output[0] = xR;
+	output[1] = xL;
+}
+
+void
+blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2],
+				iv0,
+				iv1;
+
+	Assert((len & 7) == 0);
+
+	iv0 = ctx->iv0;
+	iv1 = ctx->iv1;
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		iv0 ^= xL;
+		iv1 ^= xR;
+		blowfish_encrypt(iv0, iv1, out, ctx);
+		iv0 = out[0];
+		iv1 = out[1];
+		PUT_32BIT_MSB_FIRST(blk, iv0);
+		PUT_32BIT_MSB_FIRST(blk + 4, iv1);
+		blk += 8;
+		len -= 8;
+	}
+
+	ctx->iv0 = iv0;
+	ctx->iv1 = iv1;
+}
+
+void
+blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2],
+				iv0,
+				iv1;
+
+	Assert((len & 7) == 0);
+
+	iv0 = ctx->iv0;
+	iv1 = ctx->iv1;
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		blowfish_decrypt(xL, xR, out, ctx);
+		iv0 ^= out[0];
+		iv1 ^= out[1];
+		PUT_32BIT_MSB_FIRST(blk, iv0);
+		PUT_32BIT_MSB_FIRST(blk + 4, iv1);
+		iv0 = xL;
+		iv1 = xR;
+		blk += 8;
+		len -= 8;
+	}
+
+	ctx->iv0 = iv0;
+	ctx->iv1 = iv1;
+}
+
+void
+blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2];
+
+	Assert((len & 7) == 0);
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		blowfish_encrypt(xL, xR, out, ctx);
+		PUT_32BIT_MSB_FIRST(blk, out[0]);
+		PUT_32BIT_MSB_FIRST(blk + 4, out[1]);
+		blk += 8;
+		len -= 8;
+	}
+}
+
+void
+blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
+{
+	uint32		xL,
+				xR,
+				out[2];
+
+	Assert((len & 7) == 0);
+
+	while (len > 0)
+	{
+		xL = GET_32BIT_MSB_FIRST(blk);
+		xR = GET_32BIT_MSB_FIRST(blk + 4);
+		blowfish_decrypt(xL, xR, out, ctx);
+		PUT_32BIT_MSB_FIRST(blk, out[0]);
+		PUT_32BIT_MSB_FIRST(blk + 4, out[1]);
+		blk += 8;
+		len -= 8;
+	}
+}
+
+void
+blowfish_setkey(BlowfishContext *ctx,
+				const uint8 *key, short keybytes)
+{
+	uint32	   *S0 = ctx->S0;
+	uint32	   *S1 = ctx->S1;
+	uint32	   *S2 = ctx->S2;
+	uint32	   *S3 = ctx->S3;
+	uint32	   *P = ctx->P;
+	uint32		str[2];
+	int			i;
+
+	Assert(keybytes > 0 && keybytes <= (448 / 8));
+
+	for (i = 0; i < 18; i++)
+	{
+		P[i] = parray[i];
+		P[i] ^= ((uint32) key[(i * 4 + 0) % keybytes]) << 24;
+		P[i] ^= ((uint32) key[(i * 4 + 1) % keybytes]) << 16;
+		P[i] ^= ((uint32) key[(i * 4 + 2) % keybytes]) << 8;
+		P[i] ^= ((uint32) key[(i * 4 + 3) % keybytes]);
+	}
+
+	for (i = 0; i < 256; i++)
+	{
+		S0[i] = sbox0[i];
+		S1[i] = sbox1[i];
+		S2[i] = sbox2[i];
+		S3[i] = sbox3[i];
+	}
+
+	str[0] = str[1] = 0;
+
+	for (i = 0; i < 18; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		P[i] = str[0];
+		P[i + 1] = str[1];
+	}
+
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S0[i] = str[0];
+		S0[i + 1] = str[1];
+	}
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S1[i] = str[0];
+		S1[i + 1] = str[1];
+	}
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S2[i] = str[0];
+		S2[i + 1] = str[1];
+	}
+	for (i = 0; i < 256; i += 2)
+	{
+		blowfish_encrypt(str[0], str[1], str, ctx);
+		S3[i] = str[0];
+		S3[i + 1] = str[1];
+	}
+}
+
+void
+blowfish_setiv(BlowfishContext *ctx, const uint8 *iv)
+{
+	ctx->iv0 = GET_32BIT_MSB_FIRST(iv);
+	ctx->iv1 = GET_32BIT_MSB_FIRST(iv + 4);
+}
diff --git a/contrib/pgcrypto/blf.h b/contrib/pgcrypto/blf.h
new file mode 100644
index 0000000..84aba37
--- /dev/null
+++ b/contrib/pgcrypto/blf.h
@@ -0,0 +1,46 @@
+/* contrib/pgcrypto/blf.h */
+/*
+ * PuTTY is copyright 1997-2007 Simon Tatham.
+ *
+ * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
+ * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
+ * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
+ * Kuhn, and CORE SDI S.A.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+typedef struct
+{
+	uint32		S0[256],
+				S1[256],
+				S2[256],
+				S3[256],
+				P[18];
+	uint32		iv0,
+				iv1;			/* for CBC mode */
+} BlowfishContext;
+
+void		blowfish_setkey(BlowfishContext *ctx, const uint8 *key, short keybytes);
+void		blowfish_setiv(BlowfishContext *ctx, const uint8 *iv);
+void		blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx);
+void		blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx);
+void		blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx);
+void		blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx);
diff --git a/contrib/pgcrypto/crypt-blowfish.c b/contrib/pgcrypto/crypt-blowfish.c
new file mode 100644
index 0000000..b49747d
--- /dev/null
+++ b/contrib/pgcrypto/crypt-blowfish.c
@@ -0,0 +1,735 @@
+/*
+ * contrib/pgcrypto/crypt-blowfish.c
+ *
+ * This code comes from John the Ripper password cracker, with reentrant
+ * and crypt(3) interfaces added, but optimizations specific to password
+ * cracking removed.
+ *
+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
+ * placed in the public domain.
+ *
+ * There's absolutely no warranty.
+ *
+ * It is my intent that you should be able to use this on your system,
+ * as a part of a software package, or anywhere else to improve security,
+ * ensure compatibility, or for any other purpose. I would appreciate
+ * it if you give credit where it is due and keep your modifications in
+ * the public domain as well, but I don't require that in order to let
+ * you place this code and any modifications you make under a license
+ * of your choice.
+ *
+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
+ * ideas.  The password hashing algorithm was designed by David Mazieres
+ * <dm at lcs.mit.edu>.
+ *
+ * There's a paper on the algorithm that explains its design decisions:
+ *
+ *	http://www.usenix.org/events/usenix99/provos.html
+ *
+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
+ * Blowfish library (I can't be sure if I would think of something if I
+ * hadn't seen his code).
+ */
+
+#include "postgres.h"
+
+#include "px-crypt.h"
+
+#ifdef __i386__
+#define BF_ASM				0	/* 1 */
+#define BF_SCALE			1
+#elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__)
+#define BF_ASM				0
+#define BF_SCALE			1
+#else
+#define BF_ASM				0
+#define BF_SCALE			0
+#endif
+
+typedef unsigned int BF_word;
+typedef signed int BF_word_signed;
+
+/* Number of Blowfish rounds, this is also hardcoded into a few places */
+#define BF_N				16
+
+typedef BF_word BF_key[BF_N + 2];
+
+typedef struct
+{
+	BF_word		S[4][0x100];
+	BF_key		P;
+} BF_ctx;
+
+/*
+ * Magic IV for 64 Blowfish encryptions that we do at the end.
+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
+ */
+static BF_word BF_magic_w[6] = {
+	0x4F727068, 0x65616E42, 0x65686F6C,
+	0x64657253, 0x63727944, 0x6F756274
+};
+
+/*
+ * P-box and S-box tables initialized with digits of Pi.
+ */
+static BF_ctx BF_init_state = {
+	{
+		{
+			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+			0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+		}, {
+			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+			0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+		}, {
+			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+			0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+		}, {
+			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+			0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+		}
+	}, {
+		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+		0x9216d5d9, 0x8979fb1b
+	}
+};
+
+static unsigned char BF_itoa64[64 + 1] =
+"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static unsigned char BF_atoi64[0x60] = {
+	64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
+	54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
+	64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
+	64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+	43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
+};
+
+#define BF_safe_atoi64(dst, src) \
+do { \
+	tmp = (unsigned char)(src); \
+	if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
+	tmp = BF_atoi64[tmp]; \
+	if (tmp > 63) return -1; \
+	(dst) = tmp; \
+} while (0)
+
+static int
+BF_decode(BF_word *dst, const char *src, int size)
+{
+	unsigned char *dptr = (unsigned char *) dst;
+	unsigned char *end = dptr + size;
+	const unsigned char *sptr = (const unsigned char *) src;
+	unsigned int tmp,
+				c1,
+				c2,
+				c3,
+				c4;
+
+	do
+	{
+		BF_safe_atoi64(c1, *sptr++);
+		BF_safe_atoi64(c2, *sptr++);
+		*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
+		if (dptr >= end)
+			break;
+
+		BF_safe_atoi64(c3, *sptr++);
+		*dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
+		if (dptr >= end)
+			break;
+
+		BF_safe_atoi64(c4, *sptr++);
+		*dptr++ = ((c3 & 0x03) << 6) | c4;
+	} while (dptr < end);
+
+	return 0;
+}
+
+static void
+BF_encode(char *dst, const BF_word *src, int size)
+{
+	const unsigned char *sptr = (const unsigned char *) src;
+	const unsigned char *end = sptr + size;
+	unsigned char *dptr = (unsigned char *) dst;
+	unsigned int c1,
+				c2;
+
+	do
+	{
+		c1 = *sptr++;
+		*dptr++ = BF_itoa64[c1 >> 2];
+		c1 = (c1 & 0x03) << 4;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 4;
+		*dptr++ = BF_itoa64[c1];
+		c1 = (c2 & 0x0f) << 2;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 6;
+		*dptr++ = BF_itoa64[c1];
+		*dptr++ = BF_itoa64[c2 & 0x3f];
+	} while (sptr < end);
+}
+
+static void
+BF_swap(BF_word *x, int count)
+{
+	/* Swap on little-endian hardware, else do nothing */
+#ifndef WORDS_BIGENDIAN
+	BF_word		tmp;
+
+	do
+	{
+		tmp = *x;
+		tmp = (tmp << 16) | (tmp >> 16);
+		*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
+	} while (--count);
+#endif
+}
+
+#if BF_SCALE
+/* Architectures which can shift addresses left by 2 bits with no extra cost */
+#define BF_ROUND(L, R, N) \
+	tmp1 = (L) & 0xFF; \
+	tmp2 = (L) >> 8; \
+	tmp2 &= 0xFF; \
+	tmp3 = (L) >> 16; \
+	tmp3 &= 0xFF; \
+	tmp4 = (L) >> 24; \
+	tmp1 = data.ctx.S[3][tmp1]; \
+	tmp2 = data.ctx.S[2][tmp2]; \
+	tmp3 = data.ctx.S[1][tmp3]; \
+	tmp3 += data.ctx.S[0][tmp4]; \
+	tmp3 ^= tmp2; \
+	(R) ^= data.ctx.P[(N) + 1]; \
+	tmp3 += tmp1; \
+	(R) ^= tmp3;
+#else
+/* Architectures with no complicated addressing modes supported */
+#define BF_INDEX(S, i) \
+	(*((BF_word *)(((unsigned char *)(S)) + (i))))
+#define BF_ROUND(L, R, N) \
+	tmp1 = (L) & 0xFF; \
+	tmp1 <<= 2; \
+	tmp2 = (L) >> 6; \
+	tmp2 &= 0x3FC; \
+	tmp3 = (L) >> 14; \
+	tmp3 &= 0x3FC; \
+	tmp4 = (L) >> 22; \
+	tmp4 &= 0x3FC; \
+	tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
+	tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
+	tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
+	tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
+	tmp3 ^= tmp2; \
+	(R) ^= data.ctx.P[(N) + 1]; \
+	tmp3 += tmp1; \
+	(R) ^= tmp3;
+#endif
+
+/*
+ * Encrypt one block, BF_N is hardcoded here.
+ */
+#define BF_ENCRYPT \
+	L ^= data.ctx.P[0]; \
+	BF_ROUND(L, R, 0); \
+	BF_ROUND(R, L, 1); \
+	BF_ROUND(L, R, 2); \
+	BF_ROUND(R, L, 3); \
+	BF_ROUND(L, R, 4); \
+	BF_ROUND(R, L, 5); \
+	BF_ROUND(L, R, 6); \
+	BF_ROUND(R, L, 7); \
+	BF_ROUND(L, R, 8); \
+	BF_ROUND(R, L, 9); \
+	BF_ROUND(L, R, 10); \
+	BF_ROUND(R, L, 11); \
+	BF_ROUND(L, R, 12); \
+	BF_ROUND(R, L, 13); \
+	BF_ROUND(L, R, 14); \
+	BF_ROUND(R, L, 15); \
+	tmp4 = R; \
+	R = L; \
+	L = tmp4 ^ data.ctx.P[BF_N + 1];
+
+#if BF_ASM
+
+extern void _BF_body_r(BF_ctx *ctx);
+
+#define BF_body() \
+	_BF_body_r(&data.ctx);
+#else
+
+#define BF_body() \
+	L = R = 0; \
+	ptr = data.ctx.P; \
+	do { \
+		ptr += 2; \
+		BF_ENCRYPT; \
+		*(ptr - 2) = L; \
+		*(ptr - 1) = R; \
+	} while (ptr < &data.ctx.P[BF_N + 2]); \
+\
+	ptr = data.ctx.S[0]; \
+	do { \
+		ptr += 2; \
+		BF_ENCRYPT; \
+		*(ptr - 2) = L; \
+		*(ptr - 1) = R; \
+	} while (ptr < &data.ctx.S[3][0xFF]);
+#endif
+
+static void
+BF_set_key(const char *key, BF_key expanded, BF_key initial,
+		   int sign_extension_bug)
+{
+	const char *ptr = key;
+	int			i,
+				j;
+	BF_word		tmp;
+
+	for (i = 0; i < BF_N + 2; i++)
+	{
+		tmp = 0;
+		for (j = 0; j < 4; j++)
+		{
+			tmp <<= 8;
+			if (sign_extension_bug)
+				tmp |= (BF_word_signed) (signed char) *ptr;
+			else
+				tmp |= (unsigned char) *ptr;
+
+			if (!*ptr)
+				ptr = key;
+			else
+				ptr++;
+		}
+
+		expanded[i] = tmp;
+		initial[i] = BF_init_state.P[i] ^ tmp;
+	}
+}
+
+char *
+_crypt_blowfish_rn(const char *key, const char *setting,
+				   char *output, int size)
+{
+	struct
+	{
+		BF_ctx		ctx;
+		BF_key		expanded_key;
+		union
+		{
+			BF_word		salt[4];
+			BF_word		output[6];
+		}			binary;
+	}			data;
+	BF_word		L,
+				R;
+	BF_word		tmp1,
+				tmp2,
+				tmp3,
+				tmp4;
+	BF_word    *ptr;
+	BF_word		count;
+	int			i;
+
+	if (size < 7 + 22 + 31 + 1)
+		return NULL;
+
+	if (setting[0] != '$' ||
+		setting[1] != '2' ||
+		(setting[2] != 'a' && setting[2] != 'x') ||
+		setting[3] != '$' ||
+		setting[4] < '0' || setting[4] > '3' ||
+		setting[5] < '0' || setting[5] > '9' ||
+		(setting[4] == '3' && setting[5] > '1') ||
+		setting[6] != '$')
+	{
+		return NULL;
+	}
+
+	count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
+	if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16))
+	{
+		memset(data.binary.salt, 0, sizeof(data.binary.salt));
+		return NULL;
+	}
+	BF_swap(data.binary.salt, 4);
+
+	BF_set_key(key, data.expanded_key, data.ctx.P, setting[2] == 'x');
+
+	memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
+
+	L = R = 0;
+	for (i = 0; i < BF_N + 2; i += 2)
+	{
+		L ^= data.binary.salt[i & 2];
+		R ^= data.binary.salt[(i & 2) + 1];
+		BF_ENCRYPT;
+		data.ctx.P[i] = L;
+		data.ctx.P[i + 1] = R;
+	}
+
+	ptr = data.ctx.S[0];
+	do
+	{
+		ptr += 4;
+		L ^= data.binary.salt[(BF_N + 2) & 3];
+		R ^= data.binary.salt[(BF_N + 3) & 3];
+		BF_ENCRYPT;
+		*(ptr - 4) = L;
+		*(ptr - 3) = R;
+
+		L ^= data.binary.salt[(BF_N + 4) & 3];
+		R ^= data.binary.salt[(BF_N + 5) & 3];
+		BF_ENCRYPT;
+		*(ptr - 2) = L;
+		*(ptr - 1) = R;
+	} while (ptr < &data.ctx.S[3][0xFF]);
+
+	do
+	{
+		data.ctx.P[0] ^= data.expanded_key[0];
+		data.ctx.P[1] ^= data.expanded_key[1];
+		data.ctx.P[2] ^= data.expanded_key[2];
+		data.ctx.P[3] ^= data.expanded_key[3];
+		data.ctx.P[4] ^= data.expanded_key[4];
+		data.ctx.P[5] ^= data.expanded_key[5];
+		data.ctx.P[6] ^= data.expanded_key[6];
+		data.ctx.P[7] ^= data.expanded_key[7];
+		data.ctx.P[8] ^= data.expanded_key[8];
+		data.ctx.P[9] ^= data.expanded_key[9];
+		data.ctx.P[10] ^= data.expanded_key[10];
+		data.ctx.P[11] ^= data.expanded_key[11];
+		data.ctx.P[12] ^= data.expanded_key[12];
+		data.ctx.P[13] ^= data.expanded_key[13];
+		data.ctx.P[14] ^= data.expanded_key[14];
+		data.ctx.P[15] ^= data.expanded_key[15];
+		data.ctx.P[16] ^= data.expanded_key[16];
+		data.ctx.P[17] ^= data.expanded_key[17];
+
+		BF_body();
+
+		tmp1 = data.binary.salt[0];
+		tmp2 = data.binary.salt[1];
+		tmp3 = data.binary.salt[2];
+		tmp4 = data.binary.salt[3];
+		data.ctx.P[0] ^= tmp1;
+		data.ctx.P[1] ^= tmp2;
+		data.ctx.P[2] ^= tmp3;
+		data.ctx.P[3] ^= tmp4;
+		data.ctx.P[4] ^= tmp1;
+		data.ctx.P[5] ^= tmp2;
+		data.ctx.P[6] ^= tmp3;
+		data.ctx.P[7] ^= tmp4;
+		data.ctx.P[8] ^= tmp1;
+		data.ctx.P[9] ^= tmp2;
+		data.ctx.P[10] ^= tmp3;
+		data.ctx.P[11] ^= tmp4;
+		data.ctx.P[12] ^= tmp1;
+		data.ctx.P[13] ^= tmp2;
+		data.ctx.P[14] ^= tmp3;
+		data.ctx.P[15] ^= tmp4;
+		data.ctx.P[16] ^= tmp1;
+		data.ctx.P[17] ^= tmp2;
+
+		BF_body();
+	} while (--count);
+
+	for (i = 0; i < 6; i += 2)
+	{
+		L = BF_magic_w[i];
+		R = BF_magic_w[i + 1];
+
+		count = 64;
+		do
+		{
+			BF_ENCRYPT;
+		} while (--count);
+
+		data.binary.output[i] = L;
+		data.binary.output[i + 1] = R;
+	}
+
+	memcpy(output, setting, 7 + 22 - 1);
+	output[7 + 22 - 1] = BF_itoa64[(int)
+						 BF_atoi64[(int) setting[7 + 22 - 1] - 0x20] & 0x30];
+
+/* This has to be bug-compatible with the original implementation, so
+ * only encode 23 of the 24 bytes. :-) */
+	BF_swap(data.binary.output, 6);
+	BF_encode(&output[7 + 22], data.binary.output, 23);
+	output[7 + 22 + 31] = '\0';
+
+/* Overwrite the most obvious sensitive data we have on the stack. Note
+ * that this does not guarantee there's no sensitive data left on the
+ * stack and/or in registers; I'm not aware of portable code that does. */
+	memset(&data, 0, sizeof(data));
+
+	return output;
+}
diff --git a/contrib/pgcrypto/crypt-des.c b/contrib/pgcrypto/crypt-des.c
new file mode 100644
index 0000000..cc2e76a
--- /dev/null
+++ b/contrib/pgcrypto/crypt-des.c
@@ -0,0 +1,774 @@
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * contrib/pgcrypto/crypt-des.c
+ *
+ * Copyright (c) 1994 David Burren
+ * All rights reserved.
+ *
+ * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet
+ *	this file should now *only* export crypt(), in order to make
+ *	binaries of libcrypt exportable from the USA
+ *
+ * Adapted for FreeBSD-4.0 by Mark R V Murray
+ *	this file should now *only* export crypt_des(), in order to make
+ *	a module that can be optionally included in libcrypt.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 author nor the names of other contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/secure/lib/libcrypt/crypt-des.c,v 1.12 1999/09/20 12:39:20 markm Exp $
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren <da...@werj.com.au>.
+ *
+ * An excellent reference on the underlying algorithm (and related
+ * algorithms) is:
+ *
+ *	B. Schneier, Applied Cryptography: protocols, algorithms,
+ *	and source code in C, John Wiley & Sons, 1994.
+ *
+ * Note that in that book's description of DES the lookups for the initial,
+ * pbox, and final permutations are inverted (this has been brought to the
+ * attention of the author).  A list of errata for this book has been
+ * posted to the sci.crypt newsgroup by the author and is available for FTP.
+ *
+ * ARCHITECTURE ASSUMPTIONS:
+ *	It is assumed that the 8-byte arrays passed by reference can be
+ *	addressed as arrays of uint32's (ie. the CPU is not picky about
+ *	alignment).
+ */
+
+#include "postgres.h"
+
+#include "px-crypt.h"
+
+/* for ntohl/htonl */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define _PASSWORD_EFMT1 '_'
+
+static const char _crypt_a64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static uint8 IP[64] = {
+	58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
+	62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
+	57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
+	61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
+};
+
+static uint8 inv_key_perm[64];
+static uint8 u_key_perm[56];
+static uint8 key_perm[56] = {
+	57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
+	10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
+	63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
+	14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
+};
+
+static uint8 key_shifts[16] = {
+	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+static uint8 inv_comp_perm[56];
+static uint8 comp_perm[48] = {
+	14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
+	23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
+	41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+	44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
+};
+
+/*
+ *	No E box is used, as it's replaced by some ANDs, shifts, and ORs.
+ */
+
+static uint8 u_sbox[8][64];
+static uint8 sbox[8][64] = {
+	{
+		14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
+		0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
+		4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
+		15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
+	},
+	{
+		15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
+		3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
+		0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
+		13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
+	},
+	{
+		10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
+		13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
+		13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
+		1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
+	},
+	{
+		7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
+		13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
+		10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
+		3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
+	},
+	{
+		2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
+		14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
+		4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
+		11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
+	},
+	{
+		12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
+		10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
+		9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
+		4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
+	},
+	{
+		4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
+		13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
+		1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
+		6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
+	},
+	{
+		13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
+		1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
+		7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
+		2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
+	}
+};
+
+static uint8 un_pbox[32];
+static uint8 pbox[32] = {
+	16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
+	2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
+};
+
+static uint32 _crypt_bits32[32] =
+{
+	0x80000000, 0x40000000, 0x20000000, 0x10000000,
+	0x08000000, 0x04000000, 0x02000000, 0x01000000,
+	0x00800000, 0x00400000, 0x00200000, 0x00100000,
+	0x00080000, 0x00040000, 0x00020000, 0x00010000,
+	0x00008000, 0x00004000, 0x00002000, 0x00001000,
+	0x00000800, 0x00000400, 0x00000200, 0x00000100,
+	0x00000080, 0x00000040, 0x00000020, 0x00000010,
+	0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+static uint8 _crypt_bits8[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+
+static uint32 saltbits;
+static long old_salt;
+static uint32 *bits28,
+		   *bits24;
+static uint8 init_perm[64],
+			final_perm[64];
+static uint32 en_keysl[16],
+			en_keysr[16];
+static uint32 de_keysl[16],
+			de_keysr[16];
+static int	des_initialised = 0;
+static uint8 m_sbox[4][4096];
+static uint32 psbox[4][256];
+static uint32 ip_maskl[8][256],
+			ip_maskr[8][256];
+static uint32 fp_maskl[8][256],
+			fp_maskr[8][256];
+static uint32 key_perm_maskl[8][128],
+			key_perm_maskr[8][128];
+static uint32 comp_maskl[8][128],
+			comp_maskr[8][128];
+static uint32 old_rawkey0,
+			old_rawkey1;
+
+static inline int
+ascii_to_bin(char ch)
+{
+	if (ch > 'z')
+		return (0);
+	if (ch >= 'a')
+		return (ch - 'a' + 38);
+	if (ch > 'Z')
+		return (0);
+	if (ch >= 'A')
+		return (ch - 'A' + 12);
+	if (ch > '9')
+		return (0);
+	if (ch >= '.')
+		return (ch - '.');
+	return (0);
+}
+
+static void
+des_init(void)
+{
+	int			i,
+				j,
+				b,
+				k,
+				inbit,
+				obit;
+	uint32	   *p,
+			   *il,
+			   *ir,
+			   *fl,
+			   *fr;
+
+	old_rawkey0 = old_rawkey1 = 0L;
+	saltbits = 0L;
+	old_salt = 0L;
+	bits24 = (bits28 = _crypt_bits32 + 4) + 4;
+
+	/*
+	 * Invert the S-boxes, reordering the input bits.
+	 */
+	for (i = 0; i < 8; i++)
+		for (j = 0; j < 64; j++)
+		{
+			b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
+			u_sbox[i][j] = sbox[i][b];
+		}
+
+	/*
+	 * Convert the inverted S-boxes into 4 arrays of 8 bits. Each will handle
+	 * 12 bits of the S-box input.
+	 */
+	for (b = 0; b < 4; b++)
+		for (i = 0; i < 64; i++)
+			for (j = 0; j < 64; j++)
+				m_sbox[b][(i << 6) | j] =
+					(u_sbox[(b << 1)][i] << 4) |
+					u_sbox[(b << 1) + 1][j];
+
+	/*
+	 * Set up the initial & final permutations into a useful form, and
+	 * initialise the inverted key permutation.
+	 */
+	for (i = 0; i < 64; i++)
+	{
+		init_perm[final_perm[i] = IP[i] - 1] = i;
+		inv_key_perm[i] = 255;
+	}
+
+	/*
+	 * Invert the key permutation and initialise the inverted key compression
+	 * permutation.
+	 */
+	for (i = 0; i < 56; i++)
+	{
+		u_key_perm[i] = key_perm[i] - 1;
+		inv_key_perm[key_perm[i] - 1] = i;
+		inv_comp_perm[i] = 255;
+	}
+
+	/*
+	 * Invert the key compression permutation.
+	 */
+	for (i = 0; i < 48; i++)
+		inv_comp_perm[comp_perm[i] - 1] = i;
+
+	/*
+	 * Set up the OR-mask arrays for the initial and final permutations, and
+	 * for the key initial and compression permutations.
+	 */
+	for (k = 0; k < 8; k++)
+	{
+		for (i = 0; i < 256; i++)
+		{
+			*(il = &ip_maskl[k][i]) = 0L;
+			*(ir = &ip_maskr[k][i]) = 0L;
+			*(fl = &fp_maskl[k][i]) = 0L;
+			*(fr = &fp_maskr[k][i]) = 0L;
+			for (j = 0; j < 8; j++)
+			{
+				inbit = 8 * k + j;
+				if (i & _crypt_bits8[j])
+				{
+					if ((obit = init_perm[inbit]) < 32)
+						*il |= _crypt_bits32[obit];
+					else
+						*ir |= _crypt_bits32[obit - 32];
+					if ((obit = final_perm[inbit]) < 32)
+						*fl |= _crypt_bits32[obit];
+					else
+						*fr |= _crypt_bits32[obit - 32];
+				}
+			}
+		}
+		for (i = 0; i < 128; i++)
+		{
+			*(il = &key_perm_maskl[k][i]) = 0L;
+			*(ir = &key_perm_maskr[k][i]) = 0L;
+			for (j = 0; j < 7; j++)
+			{
+				inbit = 8 * k + j;
+				if (i & _crypt_bits8[j + 1])
+				{
+					if ((obit = inv_key_perm[inbit]) == 255)
+						continue;
+					if (obit < 28)
+						*il |= bits28[obit];
+					else
+						*ir |= bits28[obit - 28];
+				}
+			}
+			*(il = &comp_maskl[k][i]) = 0L;
+			*(ir = &comp_maskr[k][i]) = 0L;
+			for (j = 0; j < 7; j++)
+			{
+				inbit = 7 * k + j;
+				if (i & _crypt_bits8[j + 1])
+				{
+					if ((obit = inv_comp_perm[inbit]) == 255)
+						continue;
+					if (obit < 24)
+						*il |= bits24[obit];
+					else
+						*ir |= bits24[obit - 24];
+				}
+			}
+		}
+	}
+
+	/*
+	 * Invert the P-box permutation, and convert into OR-masks for handling
+	 * the output of the S-box arrays setup above.
+	 */
+	for (i = 0; i < 32; i++)
+		un_pbox[pbox[i] - 1] = i;
+
+	for (b = 0; b < 4; b++)
+		for (i = 0; i < 256; i++)
+		{
+			*(p = &psbox[b][i]) = 0L;
+			for (j = 0; j < 8; j++)
+			{
+				if (i & _crypt_bits8[j])
+					*p |= _crypt_bits32[un_pbox[8 * b + j]];
+			}
+		}
+
+	des_initialised = 1;
+}
+
+static void
+setup_salt(long salt)
+{
+	uint32		obit,
+				saltbit;
+	int			i;
+
+	if (salt == old_salt)
+		return;
+	old_salt = salt;
+
+	saltbits = 0L;
+	saltbit = 1;
+	obit = 0x800000;
+	for (i = 0; i < 24; i++)
+	{
+		if (salt & saltbit)
+			saltbits |= obit;
+		saltbit <<= 1;
+		obit >>= 1;
+	}
+}
+
+static int
+des_setkey(const char *key)
+{
+	uint32		k0,
+				k1,
+				rawkey0,
+				rawkey1;
+	int			shifts,
+				round;
+
+	if (!des_initialised)
+		des_init();
+
+	rawkey0 = ntohl(*(const uint32 *) key);
+	rawkey1 = ntohl(*(const uint32 *) (key + 4));
+
+	if ((rawkey0 | rawkey1)
+		&& rawkey0 == old_rawkey0
+		&& rawkey1 == old_rawkey1)
+	{
+		/*
+		 * Already setup for this key. This optimisation fails on a zero key
+		 * (which is weak and has bad parity anyway) in order to simplify the
+		 * starting conditions.
+		 */
+		return (0);
+	}
+	old_rawkey0 = rawkey0;
+	old_rawkey1 = rawkey1;
+
+	/*
+	 * Do key permutation and split into two 28-bit subkeys.
+	 */
+	k0 = key_perm_maskl[0][rawkey0 >> 25]
+		| key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
+		| key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
+		| key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
+		| key_perm_maskl[4][rawkey1 >> 25]
+		| key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
+		| key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
+		| key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
+	k1 = key_perm_maskr[0][rawkey0 >> 25]
+		| key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
+		| key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
+		| key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
+		| key_perm_maskr[4][rawkey1 >> 25]
+		| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
+		| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
+		| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
+
+	/*
+	 * Rotate subkeys and do compression permutation.
+	 */
+	shifts = 0;
+	for (round = 0; round < 16; round++)
+	{
+		uint32		t0,
+					t1;
+
+		shifts += key_shifts[round];
+
+		t0 = (k0 << shifts) | (k0 >> (28 - shifts));
+		t1 = (k1 << shifts) | (k1 >> (28 - shifts));
+
+		de_keysl[15 - round] =
+			en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
+			| comp_maskl[1][(t0 >> 14) & 0x7f]
+			| comp_maskl[2][(t0 >> 7) & 0x7f]
+			| comp_maskl[3][t0 & 0x7f]
+			| comp_maskl[4][(t1 >> 21) & 0x7f]
+			| comp_maskl[5][(t1 >> 14) & 0x7f]
+			| comp_maskl[6][(t1 >> 7) & 0x7f]
+			| comp_maskl[7][t1 & 0x7f];
+
+		de_keysr[15 - round] =
+			en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
+			| comp_maskr[1][(t0 >> 14) & 0x7f]
+			| comp_maskr[2][(t0 >> 7) & 0x7f]
+			| comp_maskr[3][t0 & 0x7f]
+			| comp_maskr[4][(t1 >> 21) & 0x7f]
+			| comp_maskr[5][(t1 >> 14) & 0x7f]
+			| comp_maskr[6][(t1 >> 7) & 0x7f]
+			| comp_maskr[7][t1 & 0x7f];
+	}
+	return (0);
+}
+
+static int
+do_des(uint32 l_in, uint32 r_in, uint32 *l_out, uint32 *r_out, int count)
+{
+	/*
+	 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
+	 */
+	uint32		l,
+				r,
+			   *kl,
+			   *kr,
+			   *kl1,
+			   *kr1;
+	uint32		f,
+				r48l,
+				r48r;
+	int			round;
+
+	if (count == 0)
+		return (1);
+	else if (count > 0)
+	{
+		/*
+		 * Encrypting
+		 */
+		kl1 = en_keysl;
+		kr1 = en_keysr;
+	}
+	else
+	{
+		/*
+		 * Decrypting
+		 */
+		count = -count;
+		kl1 = de_keysl;
+		kr1 = de_keysr;
+	}
+
+	/*
+	 * Do initial permutation (IP).
+	 */
+	l = ip_maskl[0][l_in >> 24]
+		| ip_maskl[1][(l_in >> 16) & 0xff]
+		| ip_maskl[2][(l_in >> 8) & 0xff]
+		| ip_maskl[3][l_in & 0xff]
+		| ip_maskl[4][r_in >> 24]
+		| ip_maskl[5][(r_in >> 16) & 0xff]
+		| ip_maskl[6][(r_in >> 8) & 0xff]
+		| ip_maskl[7][r_in & 0xff];
+	r = ip_maskr[0][l_in >> 24]
+		| ip_maskr[1][(l_in >> 16) & 0xff]
+		| ip_maskr[2][(l_in >> 8) & 0xff]
+		| ip_maskr[3][l_in & 0xff]
+		| ip_maskr[4][r_in >> 24]
+		| ip_maskr[5][(r_in >> 16) & 0xff]
+		| ip_maskr[6][(r_in >> 8) & 0xff]
+		| ip_maskr[7][r_in & 0xff];
+
+	while (count--)
+	{
+		/*
+		 * Do each round.
+		 */
+		kl = kl1;
+		kr = kr1;
+		round = 16;
+		while (round--)
+		{
+			/*
+			 * Expand R to 48 bits (simulate the E-box).
+			 */
+			r48l = ((r & 0x00000001) << 23)
+				| ((r & 0xf8000000) >> 9)
+				| ((r & 0x1f800000) >> 11)
+				| ((r & 0x01f80000) >> 13)
+				| ((r & 0x001f8000) >> 15);
+
+			r48r = ((r & 0x0001f800) << 7)
+				| ((r & 0x00001f80) << 5)
+				| ((r & 0x000001f8) << 3)
+				| ((r & 0x0000001f) << 1)
+				| ((r & 0x80000000) >> 31);
+
+			/*
+			 * Do salting for crypt() and friends, and XOR with the permuted
+			 * key.
+			 */
+			f = (r48l ^ r48r) & saltbits;
+			r48l ^= f ^ *kl++;
+			r48r ^= f ^ *kr++;
+
+			/*
+			 * Do sbox lookups (which shrink it back to 32 bits) and do the
+			 * pbox permutation at the same time.
+			 */
+			f = psbox[0][m_sbox[0][r48l >> 12]]
+				| psbox[1][m_sbox[1][r48l & 0xfff]]
+				| psbox[2][m_sbox[2][r48r >> 12]]
+				| psbox[3][m_sbox[3][r48r & 0xfff]];
+
+			/*
+			 * Now that we've permuted things, complete f().
+			 */
+			f ^= l;
+			l = r;
+			r = f;
+		}
+		r = l;
+		l = f;
+	}
+
+	/*
+	 * Do final permutation (inverse of IP).
+	 */
+	*l_out = fp_maskl[0][l >> 24]
+		| fp_maskl[1][(l >> 16) & 0xff]
+		| fp_maskl[2][(l >> 8) & 0xff]
+		| fp_maskl[3][l & 0xff]
+		| fp_maskl[4][r >> 24]
+		| fp_maskl[5][(r >> 16) & 0xff]
+		| fp_maskl[6][(r >> 8) & 0xff]
+		| fp_maskl[7][r & 0xff];
+	*r_out = fp_maskr[0][l >> 24]
+		| fp_maskr[1][(l >> 16) & 0xff]
+		| fp_maskr[2][(l >> 8) & 0xff]
+		| fp_maskr[3][l & 0xff]
+		| fp_maskr[4][r >> 24]
+		| fp_maskr[5][(r >> 16) & 0xff]
+		| fp_maskr[6][(r >> 8) & 0xff]
+		| fp_maskr[7][r & 0xff];
+	return (0);
+}
+
+static int
+des_cipher(const char *in, char *out, long salt, int count)
+{
+	uint32		buffer[2];
+	uint32		l_out,
+				r_out,
+				rawl,
+				rawr;
+	int			retval;
+
+	if (!des_initialised)
+		des_init();
+
+	setup_salt(salt);
+
+	/* copy data to avoid assuming input is word-aligned */
+	memcpy(buffer, in, sizeof(buffer));
+
+	rawl = ntohl(buffer[0]);
+	rawr = ntohl(buffer[1]);
+
+	retval = do_des(rawl, rawr, &l_out, &r_out, count);
+
+	buffer[0] = htonl(l_out);
+	buffer[1] = htonl(r_out);
+
+	/* copy data to avoid assuming output is word-aligned */
+	memcpy(out, buffer, sizeof(buffer));
+
+	return (retval);
+}
+
+char *
+px_crypt_des(const char *key, const char *setting)
+{
+	int			i;
+	uint32		count,
+				salt,
+				l,
+				r0,
+				r1,
+				keybuf[2];
+	char	   *p;
+	uint8	   *q;
+	static char output[21];
+
+	if (!des_initialised)
+		des_init();
+
+
+	/*
+	 * Copy the key, shifting each character up by one bit and padding with
+	 * zeros.
+	 */
+	q = (uint8 *) keybuf;
+	while (q - (uint8 *) keybuf - 8)
+	{
+		*q++ = *key << 1;
+		if (*key != '\0')
+			key++;
+	}
+	if (des_setkey((char *) keybuf))
+		return (NULL);
+
+#ifndef DISABLE_XDES
+	if (*setting == _PASSWORD_EFMT1)
+	{
+		/*
+		 * "new"-style: setting - underscore, 4 bytes of count, 4 bytes of
+		 * salt key - unlimited characters
+		 */
+		for (i = 1, count = 0L; i < 5; i++)
+			count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
+
+		for (i = 5, salt = 0L; i < 9; i++)
+			salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
+
+		while (*key)
+		{
+			/*
+			 * Encrypt the key with itself.
+			 */
+			if (des_cipher((char *) keybuf, (char *) keybuf, 0L, 1))
+				return (NULL);
+
+			/*
+			 * And XOR with the next 8 characters of the key.
+			 */
+			q = (uint8 *) keybuf;
+			while (q - (uint8 *) keybuf - 8 && *key)
+				*q++ ^= *key++ << 1;
+
+			if (des_setkey((char *) keybuf))
+				return (NULL);
+		}
+		strncpy(output, setting, 9);
+
+		/*
+		 * Double check that we weren't given a short setting. If we were, the
+		 * above code will probably have created weird values for count and
+		 * salt, but we don't really care. Just make sure the output string
+		 * doesn't have an extra NUL in it.
+		 */
+		output[9] = '\0';
+		p = output + strlen(output);
+	}
+	else
+#endif   /* !DISABLE_XDES */
+	{
+		/*
+		 * "old"-style: setting - 2 bytes of salt key - up to 8 characters
+		 */
+		count = 25;
+
+		salt = (ascii_to_bin(setting[1]) << 6)
+			| ascii_to_bin(setting[0]);
+
+		output[0] = setting[0];
+
+		/*
+		 * If the encrypted password that the salt was extracted from is only
+		 * 1 character long, the salt will be corrupted.  We need to ensure
+		 * that the output string doesn't have an extra NUL in it!
+		 */
+		output[1] = setting[1] ? setting[1] : output[0];
+
+		p = output + 2;
+	}
+	setup_salt(salt);
+
+	/*
+	 * Do it.
+	 */
+	if (do_des(0L, 0L, &r0, &r1, count))
+		return (NULL);
+
+	/*
+	 * Now encode the result...
+	 */
+	l = (r0 >> 8);
+	*p++ = _crypt_a64[(l >> 18) & 0x3f];
+	*p++ = _crypt_a64[(l >> 12) & 0x3f];
+	*p++ = _crypt_a64[(l >> 6) & 0x3f];
+	*p++ = _crypt_a64[l & 0x3f];
+
+	l = (r0 << 16) | ((r1 >> 16) & 0xffff);
+	*p++ = _crypt_a64[(l >> 18) & 0x3f];
+	*p++ = _crypt_a64[(l >> 12) & 0x3f];
+	*p++ = _crypt_a64[(l >> 6) & 0x3f];
+	*p++ = _crypt_a64[l & 0x3f];
+
+	l = r1 << 2;
+	*p++ = _crypt_a64[(l >> 12) & 0x3f];
+	*p++ = _crypt_a64[(l >> 6) & 0x3f];
+	*p++ = _crypt_a64[l & 0x3f];
+	*p = 0;
+
+	return (output);
+}
diff --git a/contrib/pgcrypto/crypt-gensalt.c b/contrib/pgcrypto/crypt-gensalt.c
new file mode 100644
index 0000000..ec2e0fa
--- /dev/null
+++ b/contrib/pgcrypto/crypt-gensalt.c
@@ -0,0 +1,187 @@
+/*
+ * Written by Solar Designer and placed in the public domain.
+ * See crypt_blowfish.c for more information.
+ *
+ * contrib/pgcrypto/crypt-gensalt.c
+ *
+ * This file contains salt generation functions for the traditional and
+ * other common crypt(3) algorithms, except for bcrypt which is defined
+ * entirely in crypt_blowfish.c.
+ *
+ * Put bcrypt generator also here as crypt-blowfish.c
+ * may not be compiled always.		  -- marko
+ */
+
+#include "postgres.h"
+
+#include "px-crypt.h"
+
+typedef unsigned int BF_word;
+
+static unsigned char _crypt_itoa64[64 + 1] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+char *
+_crypt_gensalt_traditional_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	if (size < 2 || output_size < 2 + 1 || (count && count != 25))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	output[0] = _crypt_itoa64[(unsigned int) input[0] & 0x3f];
+	output[1] = _crypt_itoa64[(unsigned int) input[1] & 0x3f];
+	output[2] = '\0';
+
+	return output;
+}
+
+char *
+_crypt_gensalt_extended_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	unsigned long value;
+
+/* Even iteration counts make it easier to detect weak DES keys from a look
+ * at the hash, so they should be avoided */
+	if (size < 3 || output_size < 1 + 4 + 4 + 1 ||
+		(count && (count > 0xffffff || !(count & 1))))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	if (!count)
+		count = 725;
+
+	output[0] = '_';
+	output[1] = _crypt_itoa64[count & 0x3f];
+	output[2] = _crypt_itoa64[(count >> 6) & 0x3f];
+	output[3] = _crypt_itoa64[(count >> 12) & 0x3f];
+	output[4] = _crypt_itoa64[(count >> 18) & 0x3f];
+	value = (unsigned long) (unsigned char) input[0] |
+		((unsigned long) (unsigned char) input[1] << 8) |
+		((unsigned long) (unsigned char) input[2] << 16);
+	output[5] = _crypt_itoa64[value & 0x3f];
+	output[6] = _crypt_itoa64[(value >> 6) & 0x3f];
+	output[7] = _crypt_itoa64[(value >> 12) & 0x3f];
+	output[8] = _crypt_itoa64[(value >> 18) & 0x3f];
+	output[9] = '\0';
+
+	return output;
+}
+
+char *
+_crypt_gensalt_md5_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	unsigned long value;
+
+	if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	output[0] = '$';
+	output[1] = '1';
+	output[2] = '$';
+	value = (unsigned long) (unsigned char) input[0] |
+		((unsigned long) (unsigned char) input[1] << 8) |
+		((unsigned long) (unsigned char) input[2] << 16);
+	output[3] = _crypt_itoa64[value & 0x3f];
+	output[4] = _crypt_itoa64[(value >> 6) & 0x3f];
+	output[5] = _crypt_itoa64[(value >> 12) & 0x3f];
+	output[6] = _crypt_itoa64[(value >> 18) & 0x3f];
+	output[7] = '\0';
+
+	if (size >= 6 && output_size >= 3 + 4 + 4 + 1)
+	{
+		value = (unsigned long) (unsigned char) input[3] |
+			((unsigned long) (unsigned char) input[4] << 8) |
+			((unsigned long) (unsigned char) input[5] << 16);
+		output[7] = _crypt_itoa64[value & 0x3f];
+		output[8] = _crypt_itoa64[(value >> 6) & 0x3f];
+		output[9] = _crypt_itoa64[(value >> 12) & 0x3f];
+		output[10] = _crypt_itoa64[(value >> 18) & 0x3f];
+		output[11] = '\0';
+	}
+
+	return output;
+}
+
+
+
+static unsigned char BF_itoa64[64 + 1] =
+"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+static void
+BF_encode(char *dst, const BF_word *src, int size)
+{
+	const unsigned char *sptr = (const unsigned char *) src;
+	const unsigned char *end = sptr + size;
+	unsigned char *dptr = (unsigned char *) dst;
+	unsigned int c1,
+				c2;
+
+	do
+	{
+		c1 = *sptr++;
+		*dptr++ = BF_itoa64[c1 >> 2];
+		c1 = (c1 & 0x03) << 4;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 4;
+		*dptr++ = BF_itoa64[c1];
+		c1 = (c2 & 0x0f) << 2;
+		if (sptr >= end)
+		{
+			*dptr++ = BF_itoa64[c1];
+			break;
+		}
+
+		c2 = *sptr++;
+		c1 |= c2 >> 6;
+		*dptr++ = BF_itoa64[c1];
+		*dptr++ = BF_itoa64[c2 & 0x3f];
+	} while (sptr < end);
+}
+
+char *
+_crypt_gensalt_blowfish_rn(unsigned long count,
+				  const char *input, int size, char *output, int output_size)
+{
+	if (size < 16 || output_size < 7 + 22 + 1 ||
+		(count && (count < 4 || count > 31)))
+	{
+		if (output_size > 0)
+			output[0] = '\0';
+		return NULL;
+	}
+
+	if (!count)
+		count = 5;
+
+	output[0] = '$';
+	output[1] = '2';
+	output[2] = 'a';
+	output[3] = '$';
+	output[4] = '0' + count / 10;
+	output[5] = '0' + count % 10;
+	output[6] = '$';
+
+	BF_encode(&output[7], (const BF_word *) input, 16);
+	output[7 + 22] = '\0';
+
+	return output;
+}
diff --git a/contrib/pgcrypto/crypt-md5.c b/contrib/pgcrypto/crypt-md5.c
new file mode 100644
index 0000000..6c7a2b3
--- /dev/null
+++ b/contrib/pgcrypto/crypt-md5.c
@@ -0,0 +1,163 @@
+/*
+ * File imported from FreeBSD, original by Poul-Henning Kamp.
+ *
+ * $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
+ *
+ * contrib/pgcrypto/crypt-md5.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "px-crypt.h"
+
+#define MD5_SIZE 16
+
+static const char _crypt_a64[] =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void
+_crypt_to64(char *s, unsigned long v, int n)
+{
+	while (--n >= 0)
+	{
+		*s++ = _crypt_a64[v & 0x3f];
+		v >>= 6;
+	}
+}
+
+/*
+ * UNIX password
+ */
+
+char *
+px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen)
+{
+	static char *magic = "$1$"; /* This string is magic for this algorithm.
+								 * Having it this way, we can get better
+								 * later on */
+	static char *p;
+	static const char *sp,
+			   *ep;
+	unsigned char final[MD5_SIZE];
+	int			sl,
+				pl,
+				i;
+	PX_MD	   *ctx,
+			   *ctx1;
+	int			err;
+	unsigned long l;
+
+	if (!passwd || dstlen < 120)
+		return NULL;
+
+	/* Refine the Salt first */
+	sp = salt;
+
+	/* If it starts with the magic string, then skip that */
+	if (strncmp(sp, magic, strlen(magic)) == 0)
+		sp += strlen(magic);
+
+	/* It stops at the first '$', max 8 chars */
+	for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
+		continue;
+
+	/* get the length of the true salt */
+	sl = ep - sp;
+
+	/* */
+	err = px_find_digest("md5", &ctx);
+	if (err)
+		return NULL;
+	err = px_find_digest("md5", &ctx1);
+
+	/* The password first, since that is what is most unknown */
+	px_md_update(ctx, (const uint8 *) pw, strlen(pw));
+
+	/* Then our magic string */
+	px_md_update(ctx, (uint8 *) magic, strlen(magic));
+
+	/* Then the raw salt */
+	px_md_update(ctx, (const uint8 *) sp, sl);
+
+	/* Then just as many characters of the MD5(pw,salt,pw) */
+	px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+	px_md_update(ctx1, (const uint8 *) sp, sl);
+	px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+	px_md_finish(ctx1, final);
+	for (pl = strlen(pw); pl > 0; pl -= MD5_SIZE)
+		px_md_update(ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl);
+
+	/* Don't leave anything around in vm they could use. */
+	memset(final, 0, sizeof final);
+
+	/* Then something really weird... */
+	for (i = strlen(pw); i; i >>= 1)
+		if (i & 1)
+			px_md_update(ctx, final, 1);
+		else
+			px_md_update(ctx, (const uint8 *) pw, 1);
+
+	/* Now make the output string */
+	strcpy(passwd, magic);
+	strncat(passwd, sp, sl);
+	strcat(passwd, "$");
+
+	px_md_finish(ctx, final);
+
+	/*
+	 * and now, just to make sure things don't run too fast On a 60 Mhz
+	 * Pentium this takes 34 msec, so you would need 30 seconds to build a
+	 * 1000 entry dictionary...
+	 */
+	for (i = 0; i < 1000; i++)
+	{
+		px_md_reset(ctx1);
+		if (i & 1)
+			px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+		else
+			px_md_update(ctx1, final, MD5_SIZE);
+
+		if (i % 3)
+			px_md_update(ctx1, (const uint8 *) sp, sl);
+
+		if (i % 7)
+			px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+
+		if (i & 1)
+			px_md_update(ctx1, final, MD5_SIZE);
+		else
+			px_md_update(ctx1, (const uint8 *) pw, strlen(pw));
+		px_md_finish(ctx1, final);
+	}
+
+	p = passwd + strlen(passwd);
+
+	l = (final[0] << 16) | (final[6] << 8) | final[12];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[1] << 16) | (final[7] << 8) | final[13];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[2] << 16) | (final[8] << 8) | final[14];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[3] << 16) | (final[9] << 8) | final[15];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = (final[4] << 16) | (final[10] << 8) | final[5];
+	_crypt_to64(p, l, 4);
+	p += 4;
+	l = final[11];
+	_crypt_to64(p, l, 2);
+	p += 2;
+	*p = '\0';
+
+	/* Don't leave anything around in vm they could use. */
+	memset(final, 0, sizeof final);
+
+	px_md_free(ctx1);
+	px_md_free(ctx);
+
+	return passwd;
+}
diff --git a/contrib/pgcrypto/expected/3des.out b/contrib/pgcrypto/expected/3des.out
new file mode 100644
index 0000000..8983a73
--- /dev/null
+++ b/contrib/pgcrypto/expected/3des.out
@@ -0,0 +1,71 @@
+--
+-- 3DES cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- test vector from somewhere
+SELECT encode(encrypt(
+decode('80 00 00 00 00 00 00 00', 'hex'),
+decode('01 01 01 01 01 01 01 01
+	01 01 01 01 01 01 01 01
+	01 01 01 01 01 01 01 01', 'hex'),
+'3des-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 95f8a5e5dd31d900
+(1 row)
+
+-- val 95 F8 A5 E5 DD 31 D9 00
+select encode(	encrypt('', 'foo', '3des'), 'hex');
+      encode      
+------------------
+ 752111e37a2d7ac3
+(1 row)
+
+-- 10 bytes key
+select encode(	encrypt('foo', '0123456789', '3des'), 'hex');
+      encode      
+------------------
+ d2fb8baa1717cb02
+(1 row)
+
+-- 22 bytes key
+select encode(	encrypt('foo', '0123456789012345678901', '3des'), 'hex');
+      encode      
+------------------
+ a44360e699269817
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', '3des'), '0123456', '3des');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', '3des'), 'hex');
+      encode      
+------------------
+ 50735067b073bb93
+(1 row)
+
+select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', '3des');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789012345678901', '3des'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ b71e3422269d0ded19468f33d65cd663c28e0871984792a7b3ba0ddcecec8d2c
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '0123456789012345678901', '3des'), '0123456789012345678901', '3des');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+
diff --git a/contrib/pgcrypto/expected/blowfish.out b/contrib/pgcrypto/expected/blowfish.out
new file mode 100644
index 0000000..72557ea
--- /dev/null
+++ b/contrib/pgcrypto/expected/blowfish.out
@@ -0,0 +1,175 @@
+--
+-- Blowfish cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- some standard Blowfish testvalues
+SELECT encode(encrypt(
+decode('0000000000000000', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 4ef997456198dd78
+(1 row)
+
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('ffffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 51866fd5b85ecb8a
+(1 row)
+
+SELECT encode(encrypt(
+decode('1000000000000001', 'hex'),
+decode('3000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 7d856f9a613063f2
+(1 row)
+
+SELECT encode(encrypt(
+decode('1111111111111111', 'hex'),
+decode('1111111111111111', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 2466dd878b963c9d
+(1 row)
+
+SELECT encode(encrypt(
+decode('0123456789abcdef', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 0aceab0fc6a0a28d
+(1 row)
+
+SELECT encode(encrypt(
+decode('01a1d6d039776742', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 3273b8badc9e9e15
+(1 row)
+
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 014933e0cdaff6e4
+(1 row)
+
+-- setkey
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 93142887ee3be15c
+(1 row)
+
+-- with padding
+SELECT encode(encrypt(
+decode('01234567890123456789', 'hex'),
+decode('33443344334433443344334433443344', 'hex'),
+'bf-ecb'), 'hex');
+              encode              
+----------------------------------
+ 0d04a43a20456dee5ede6ed9e4dcaaa6
+(1 row)
+
+-- cbc
+-- 28 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f7220', 'hex'),
+'bf-cbc'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ 4f2beb748c4f689ec755edb9dc252a41b93a3786850b4c75d6a702b6a8e48825
+(1 row)
+
+-- 29 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f722000', 'hex'),
+'bf-cbc'), 'hex');
+                                      encode                                      
+----------------------------------------------------------------------------------
+ 3ea6357a0ee7fad6d0c4b63464f2aafa40c2e91b4b7e1bba8114932fd92b5c8f111e7e50e7b2e541
+(1 row)
+
+-- blowfish-448
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455667704689104c2fd3b2f584023641aba61761f1f1f1f0e0e0e0effffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ c04504012e4e1f53
+(1 row)
+
+-- result: c04504012e4e1f53
+-- empty data
+select encode(encrypt('', 'foo', 'bf'), 'hex');
+      encode      
+------------------
+ 1871949bb2311c8e
+(1 row)
+
+-- 10 bytes key
+select encode(encrypt('foo', '0123456789', 'bf'), 'hex');
+      encode      
+------------------
+ 42f58af3b2c03f46
+(1 row)
+
+-- 22 bytes key
+select encode(encrypt('foo', '0123456789012345678901', 'bf'), 'hex');
+      encode      
+------------------
+ 86ab6f0bc72b5f22
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'bf'), '0123456', 'bf');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'bf'), 'hex');
+      encode      
+------------------
+ 95c7e89322525d59
+(1 row)
+
+select decrypt_iv(decode('95c7e89322525d59', 'hex'), '0123456', 'abcd', 'bf');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'bf'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ a76059f7a1b627b5b84080d9beb337714c7a7f8b70300023e5feb6dfa6813536
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'bf'), '0123456789', 'bf');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+
diff --git a/contrib/pgcrypto/expected/cast5.out b/contrib/pgcrypto/expected/cast5.out
new file mode 100644
index 0000000..c1ecd91
--- /dev/null
+++ b/contrib/pgcrypto/expected/cast5.out
@@ -0,0 +1,88 @@
+--
+-- Cast5 cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- test vectors from RFC2144
+-- 128 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 238b4fe5847e44b2
+(1 row)
+
+-- result: 23 8B 4F E5 84 7E 44 B2
+-- 80 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ eb6a711a2c02271b
+(1 row)
+
+-- result: EB 6A 71 1A 2C 02 27 1B
+-- 40 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 7ac816d16e9b302e
+(1 row)
+
+-- result: 7A C8 16 D1 6E 9B 30 2E
+-- cbc
+-- empty data
+select encode(	encrypt('', 'foo', 'cast5'), 'hex');
+      encode      
+------------------
+ a48bd1aabde4de10
+(1 row)
+
+-- 10 bytes key
+select encode(	encrypt('foo', '0123456789', 'cast5'), 'hex');
+      encode      
+------------------
+ b07f19255e60cb6d
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'cast5'), '0123456', 'cast5');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'cast5'), 'hex');
+      encode      
+------------------
+ 384a970695ce016a
+(1 row)
+
+select decrypt_iv(decode('384a970695ce016a', 'hex'),
+                '0123456', 'abcd', 'cast5');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'cast5'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ 04fcffc91533e1505dadcb10766d9fed0937818e663e402384e049942ba60fff
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'cast5'), '0123456789', 'cast5');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+
diff --git a/contrib/pgcrypto/expected/crypt-blowfish.out b/contrib/pgcrypto/expected/crypt-blowfish.out
new file mode 100644
index 0000000..329d78f
--- /dev/null
+++ b/contrib/pgcrypto/expected/crypt-blowfish.out
@@ -0,0 +1,27 @@
+--
+-- crypt() and gen_salt(): bcrypt
+--
+SELECT crypt('', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O');
+                            crypt                             
+--------------------------------------------------------------
+ $2a$06$RQiOJ.3ELirrXwxIZY8q0OlGbBEpDmx7IRZlNYvGJ1SHXwNi2cEKK
+(1 row)
+
+SELECT crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O');
+                            crypt                             
+--------------------------------------------------------------
+ $2a$06$RQiOJ.3ELirrXwxIZY8q0OR3CVJrAfda1z26CCHPnB6mmVZD8p0/C
+(1 row)
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+UPDATE ctest SET salt = gen_salt('bf', 8);
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+ worked 
+--------
+ t
+(1 row)
+
+DROP TABLE ctest;
diff --git a/contrib/pgcrypto/expected/crypt-des.out b/contrib/pgcrypto/expected/crypt-des.out


<TRUNCATED>


[08/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/imath.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/imath.c b/contrib/pgcrypto/imath.c
new file mode 100644
index 0000000..3286cd9
--- /dev/null
+++ b/contrib/pgcrypto/imath.c
@@ -0,0 +1,3681 @@
+/* imath version 1.3 */
+/*
+  Name:		imath.c
+  Purpose:	Arbitrary precision integer arithmetic routines.
+  Author:	M. J. Fromberger <http://spinning-yarns.org/michael/sw/>
+  Info:		Id: imath.c 21 2006-04-02 18:58:36Z sting
+
+  Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT.	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+ */
+/* contrib/pgcrypto/imath.c */
+
+#include "postgres.h"
+#include "px.h"
+#include "imath.h"
+
+#undef assert
+#define assert(TEST) Assert(TEST)
+#define TRACEABLE_CLAMP 0
+#define TRACEABLE_FREE 0
+
+/* {{{ Constants */
+
+const mp_result MP_OK = 0;		/* no error, all is well  */
+const mp_result MP_FALSE = 0;	/* boolean false		  */
+const mp_result MP_TRUE = -1;	/* boolean true			  */
+const mp_result MP_MEMORY = -2; /* out of memory		  */
+const mp_result MP_RANGE = -3;	/* argument out of range  */
+const mp_result MP_UNDEF = -4;	/* result undefined		  */
+const mp_result MP_TRUNC = -5;	/* output truncated		  */
+const mp_result MP_BADARG = -6; /* invalid null argument  */
+
+const mp_sign MP_NEG = 1;		/* value is strictly negative */
+const mp_sign MP_ZPOS = 0;		/* value is non-negative	  */
+
+static const char *s_unknown_err = "unknown result code";
+static const char *s_error_msg[] = {
+	"error code 0",
+	"boolean true",
+	"out of memory",
+	"argument out of range",
+	"result undefined",
+	"output truncated",
+	"invalid null argument",
+	NULL
+};
+
+/* }}} */
+
+/* Optional library flags */
+#define MP_CAP_DIGITS	1		/* flag bit to capitalize letter digits */
+
+/* Argument checking macros
+   Use CHECK() where a return value is required; NRCHECK() elsewhere */
+#define CHECK(TEST)   assert(TEST)
+#define NRCHECK(TEST) assert(TEST)
+
+/* {{{ Logarithm table for computing output sizes */
+
+/* The ith entry of this table gives the value of log_i(2).
+
+   An integer value n requires ceil(log_i(n)) digits to be represented
+   in base i.  Since it is easy to compute lg(n), by counting bits, we
+   can compute log_i(n) = lg(n) * log_i(2).
+ */
+static const double s_log2[] = {
+	0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0  1  2	3 */
+	0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4  5  6	7 */
+	0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8  9 10 11 */
+	0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */
+	0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */
+	0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */
+	0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */
+	0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */
+	0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */
+	0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */
+	0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */
+	0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */
+	0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */
+	0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */
+	0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */
+	0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */
+	0.166666667
+};
+
+/* }}} */
+/* {{{ Various macros */
+
+/* Return the number of digits needed to represent a static value */
+#define MP_VALUE_DIGITS(V) \
+((sizeof(V)+(sizeof(mp_digit)-1))/sizeof(mp_digit))
+
+/* Round precision P to nearest word boundary */
+#define ROUND_PREC(P) ((mp_size)(2*(((P)+1)/2)))
+
+/* Set array P of S digits to zero */
+#define ZERO(P, S) \
+do{mp_size i__=(S)*sizeof(mp_digit);mp_digit *p__=(P);memset(p__,0,i__);}while(0)
+
+/* Copy S digits from array P to array Q */
+#define COPY(P, Q, S) \
+do{mp_size i__=(S)*sizeof(mp_digit);mp_digit *p__=(P),*q__=(Q);\
+memcpy(q__,p__,i__);}while(0)
+
+/* Reverse N elements of type T in array A */
+#define REV(T, A, N) \
+do{T *u_=(A),*v_=u_+(N)-1;while(u_<v_){T xch=*u_;*u_++=*v_;*v_--=xch;}}while(0)
+
+#if TRACEABLE_CLAMP
+#define CLAMP(Z) s_clamp(Z)
+#else
+#define CLAMP(Z) \
+do{mp_int z_=(Z);mp_size uz_=MP_USED(z_);mp_digit *dz_=MP_DIGITS(z_)+uz_-1;\
+while(uz_ > 1 && (*dz_-- == 0)) --uz_;MP_USED(z_)=uz_;}while(0)
+#endif
+
+#undef MIN
+#undef MAX
+#define MIN(A, B) ((B)<(A)?(B):(A))
+#define MAX(A, B) ((B)>(A)?(B):(A))
+#define SWAP(T, A, B) do{T t_=(A);A=(B);B=t_;}while(0)
+
+#define TEMP(K) (temp + (K))
+#define SETUP(E, C) \
+do{if((res = (E)) != MP_OK) goto CLEANUP; ++(C);}while(0)
+
+#define CMPZ(Z) \
+(((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1)
+
+#define UMUL(X, Y, Z) \
+do{mp_size ua_=MP_USED(X),ub_=MP_USED(Y);mp_size o_=ua_+ub_;\
+ZERO(MP_DIGITS(Z),o_);\
+(void) s_kmul(MP_DIGITS(X),MP_DIGITS(Y),MP_DIGITS(Z),ua_,ub_);\
+MP_USED(Z)=o_;CLAMP(Z);}while(0)
+
+#define USQR(X, Z) \
+do{mp_size ua_=MP_USED(X),o_=ua_+ua_;ZERO(MP_DIGITS(Z),o_);\
+(void) s_ksqr(MP_DIGITS(X),MP_DIGITS(Z),ua_);MP_USED(Z)=o_;CLAMP(Z);}while(0)
+
+#define UPPER_HALF(W)			((mp_word)((W) >> MP_DIGIT_BIT))
+#define LOWER_HALF(W)			((mp_digit)(W))
+#define HIGH_BIT_SET(W)			((W) >> (MP_WORD_BIT - 1))
+#define ADD_WILL_OVERFLOW(W, V) ((MP_WORD_MAX - (V)) < (W))
+
+/* }}} */
+
+/* Default number of digits allocated to a new mp_int */
+static mp_size default_precision = 64;
+
+/* Minimum number of digits to invoke recursive multiply */
+static mp_size multiply_threshold = 32;
+
+/* Default library configuration flags */
+static mp_word mp_flags = MP_CAP_DIGITS;
+
+/* Allocate a buffer of (at least) num digits, or return
+   NULL if that couldn't be done.  */
+static mp_digit *s_alloc(mp_size num);
+
+#if TRACEABLE_FREE
+static void s_free(void *ptr);
+#else
+#define s_free(P) px_free(P)
+#endif
+
+/* Insure that z has at least min digits allocated, resizing if
+   necessary.  Returns true if successful, false if out of memory. */
+static int	s_pad(mp_int z, mp_size min);
+
+/* Normalize by removing leading zeroes (except when z = 0) */
+#if TRACEABLE_CLAMP
+static void s_clamp(mp_int z);
+#endif
+
+/* Fill in a "fake" mp_int on the stack with a given value */
+static void s_fake(mp_int z, int value, mp_digit vbuf[]);
+
+/* Compare two runs of digits of given length, returns <0, 0, >0 */
+static int	s_cdig(mp_digit *da, mp_digit *db, mp_size len);
+
+/* Pack the unsigned digits of v into array t */
+static int	s_vpack(int v, mp_digit t[]);
+
+/* Compare magnitudes of a and b, returns <0, 0, >0 */
+static int	s_ucmp(mp_int a, mp_int b);
+
+/* Compare magnitudes of a and v, returns <0, 0, >0 */
+static int	s_vcmp(mp_int a, int v);
+
+/* Unsigned magnitude addition; assumes dc is big enough.
+   Carry out is returned (no memory allocated). */
+static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b);
+
+/* Unsigned magnitude subtraction.	Assumes dc is big enough. */
+static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b);
+
+/* Unsigned recursive multiplication.  Assumes dc is big enough. */
+static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b);
+
+/* Unsigned magnitude multiplication.  Assumes dc is big enough. */
+static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b);
+
+/* Unsigned recursive squaring.  Assumes dc is big enough. */
+static int	s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a);
+
+/* Unsigned magnitude squaring.  Assumes dc is big enough. */
+static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a);
+
+/* Single digit addition.  Assumes a is big enough. */
+static void s_dadd(mp_int a, mp_digit b);
+
+/* Single digit multiplication.  Assumes a is big enough. */
+static void s_dmul(mp_int a, mp_digit b);
+
+/* Single digit multiplication on buffers; assumes dc is big enough. */
+static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc,
+		mp_size size_a);
+
+/* Single digit division.  Replaces a with the quotient,
+   returns the remainder.  */
+static mp_digit s_ddiv(mp_int a, mp_digit b);
+
+/* Quick division by a power of 2, replaces z (no allocation) */
+static void s_qdiv(mp_int z, mp_size p2);
+
+/* Quick remainder by a power of 2, replaces z (no allocation) */
+static void s_qmod(mp_int z, mp_size p2);
+
+/* Quick multiplication by a power of 2, replaces z.
+   Allocates if necessary; returns false in case this fails. */
+static int	s_qmul(mp_int z, mp_size p2);
+
+/* Quick subtraction from a power of 2, replaces z.
+   Allocates if necessary; returns false in case this fails. */
+static int	s_qsub(mp_int z, mp_size p2);
+
+/* Return maximum k such that 2^k divides z. */
+static int	s_dp2k(mp_int z);
+
+/* Return k >= 0 such that z = 2^k, or -1 if there is no such k. */
+static int	s_isp2(mp_int z);
+
+/* Set z to 2^k.  May allocate; returns false in case this fails. */
+static int	s_2expt(mp_int z, int k);
+
+/* Normalize a and b for division, returns normalization constant */
+static int	s_norm(mp_int a, mp_int b);
+
+/* Compute constant mu for Barrett reduction, given modulus m, result
+   replaces z, m is untouched. */
+static mp_result s_brmu(mp_int z, mp_int m);
+
+/* Reduce a modulo m, using Barrett's algorithm. */
+static int	s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2);
+
+/* Modular exponentiation, using Barrett reduction */
+static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c);
+
+/* Unsigned magnitude division.  Assumes |a| > |b|.  Allocates
+   temporaries; overwrites a with quotient, b with remainder. */
+static mp_result s_udiv(mp_int a, mp_int b);
+
+/* Compute the number of digits in radix r required to represent the
+   given value.  Does not account for sign flags, terminators, etc. */
+static int	s_outlen(mp_int z, mp_size r);
+
+/* Guess how many digits of precision will be needed to represent a
+   radix r value of the specified number of digits.  Returns a value
+   guaranteed to be no smaller than the actual number required. */
+static mp_size s_inlen(int len, mp_size r);
+
+/* Convert a character to a digit value in radix r, or
+   -1 if out of range */
+static int	s_ch2val(char c, int r);
+
+/* Convert a digit value to a character */
+static char s_val2ch(int v, int caps);
+
+/* Take 2's complement of a buffer in place */
+static void s_2comp(unsigned char *buf, int len);
+
+/* Convert a value to binary, ignoring sign.  On input, *limpos is the
+   bound on how many bytes should be written to buf; on output, *limpos
+   is set to the number of bytes actually written. */
+static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad);
+
+#if 0
+/* Dump a representation of the mp_int to standard output */
+void		s_print(char *tag, mp_int z);
+void		s_print_buf(char *tag, mp_digit *buf, mp_size num);
+#endif
+
+/* {{{ get_default_precision() */
+
+mp_size
+mp_get_default_precision(void)
+{
+	return default_precision;
+}
+
+/* }}} */
+
+/* {{{ mp_set_default_precision(s) */
+
+void
+mp_set_default_precision(mp_size s)
+{
+	NRCHECK(s > 0);
+
+	default_precision = (mp_size) ROUND_PREC(s);
+}
+
+/* }}} */
+
+/* {{{ mp_get_multiply_threshold() */
+
+mp_size
+mp_get_multiply_threshold(void)
+{
+	return multiply_threshold;
+}
+
+/* }}} */
+
+/* {{{ mp_set_multiply_threshold(s) */
+
+void
+mp_set_multiply_threshold(mp_size s)
+{
+	multiply_threshold = s;
+}
+
+/* }}} */
+
+/* {{{ mp_int_init(z) */
+
+mp_result
+mp_int_init(mp_int z)
+{
+	return mp_int_init_size(z, default_precision);
+}
+
+/* }}} */
+
+/* {{{ mp_int_alloc() */
+
+mp_int
+mp_int_alloc(void)
+{
+	mp_int		out = px_alloc(sizeof(mpz_t));
+
+	assert(out != NULL);
+	out->digits = NULL;
+	out->used = 0;
+	out->alloc = 0;
+	out->sign = 0;
+
+	return out;
+}
+
+/* }}} */
+
+/* {{{ mp_int_init_size(z, prec) */
+
+mp_result
+mp_int_init_size(mp_int z, mp_size prec)
+{
+	CHECK(z != NULL);
+
+	prec = (mp_size) ROUND_PREC(prec);
+	prec = MAX(prec, default_precision);
+
+	if ((MP_DIGITS(z) = s_alloc(prec)) == NULL)
+		return MP_MEMORY;
+
+	z->digits[0] = 0;
+	MP_USED(z) = 1;
+	MP_ALLOC(z) = prec;
+	MP_SIGN(z) = MP_ZPOS;
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_init_copy(z, old) */
+
+mp_result
+mp_int_init_copy(mp_int z, mp_int old)
+{
+	mp_result	res;
+	mp_size		uold,
+				target;
+
+	CHECK(z != NULL && old != NULL);
+
+	uold = MP_USED(old);
+	target = MAX(uold, default_precision);
+
+	if ((res = mp_int_init_size(z, target)) != MP_OK)
+		return res;
+
+	MP_USED(z) = uold;
+	MP_SIGN(z) = MP_SIGN(old);
+	COPY(MP_DIGITS(old), MP_DIGITS(z), uold);
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_init_value(z, value) */
+
+mp_result
+mp_int_init_value(mp_int z, int value)
+{
+	mp_result	res;
+
+	CHECK(z != NULL);
+
+	if ((res = mp_int_init(z)) != MP_OK)
+		return res;
+
+	return mp_int_set_value(z, value);
+}
+
+/* }}} */
+
+/* {{{ mp_int_set_value(z, value) */
+
+mp_result
+mp_int_set_value(mp_int z, int value)
+{
+	mp_size		ndig;
+
+	CHECK(z != NULL);
+
+	/* How many digits to copy */
+	ndig = (mp_size) MP_VALUE_DIGITS(value);
+
+	if (!s_pad(z, ndig))
+		return MP_MEMORY;
+
+	MP_USED(z) = (mp_size) s_vpack(value, MP_DIGITS(z));
+	MP_SIGN(z) = (value < 0) ? MP_NEG : MP_ZPOS;
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_clear(z) */
+
+void
+mp_int_clear(mp_int z)
+{
+	if (z == NULL)
+		return;
+
+	if (MP_DIGITS(z) != NULL)
+	{
+		s_free(MP_DIGITS(z));
+		MP_DIGITS(z) = NULL;
+	}
+}
+
+/* }}} */
+
+/* {{{ mp_int_free(z) */
+
+void
+mp_int_free(mp_int z)
+{
+	NRCHECK(z != NULL);
+
+	if (z->digits != NULL)
+		mp_int_clear(z);
+
+	px_free(z);
+}
+
+/* }}} */
+
+/* {{{ mp_int_copy(a, c) */
+
+mp_result
+mp_int_copy(mp_int a, mp_int c)
+{
+	CHECK(a != NULL && c != NULL);
+
+	if (a != c)
+	{
+		mp_size		ua = MP_USED(a);
+		mp_digit   *da,
+				   *dc;
+
+		if (!s_pad(c, ua))
+			return MP_MEMORY;
+
+		da = MP_DIGITS(a);
+		dc = MP_DIGITS(c);
+		COPY(da, dc, ua);
+
+		MP_USED(c) = ua;
+		MP_SIGN(c) = MP_SIGN(a);
+	}
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_swap(a, c) */
+
+void
+mp_int_swap(mp_int a, mp_int c)
+{
+	if (a != c)
+	{
+		mpz_t		tmp = *a;
+
+		*a = *c;
+		*c = tmp;
+	}
+}
+
+/* }}} */
+
+/* {{{ mp_int_zero(z) */
+
+void
+mp_int_zero(mp_int z)
+{
+	NRCHECK(z != NULL);
+
+	z->digits[0] = 0;
+	MP_USED(z) = 1;
+	MP_SIGN(z) = MP_ZPOS;
+}
+
+/* }}} */
+
+/* {{{ mp_int_abs(a, c) */
+
+mp_result
+mp_int_abs(mp_int a, mp_int c)
+{
+	mp_result	res;
+
+	CHECK(a != NULL && c != NULL);
+
+	if ((res = mp_int_copy(a, c)) != MP_OK)
+		return res;
+
+	MP_SIGN(c) = MP_ZPOS;
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_neg(a, c) */
+
+mp_result
+mp_int_neg(mp_int a, mp_int c)
+{
+	mp_result	res;
+
+	CHECK(a != NULL && c != NULL);
+
+	if ((res = mp_int_copy(a, c)) != MP_OK)
+		return res;
+
+	if (CMPZ(c) != 0)
+		MP_SIGN(c) = 1 - MP_SIGN(a);
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_add(a, b, c) */
+
+mp_result
+mp_int_add(mp_int a, mp_int b, mp_int c)
+{
+	mp_size		ua,
+				ub,
+				uc,
+				max;
+
+	CHECK(a != NULL && b != NULL && c != NULL);
+
+	ua = MP_USED(a);
+	ub = MP_USED(b);
+	uc = MP_USED(c);
+	max = MAX(ua, ub);
+
+	if (MP_SIGN(a) == MP_SIGN(b))
+	{
+		/* Same sign -- add magnitudes, preserve sign of addends */
+		mp_digit	carry;
+
+		if (!s_pad(c, max))
+			return MP_MEMORY;
+
+		carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
+		uc = max;
+
+		if (carry)
+		{
+			if (!s_pad(c, max + 1))
+				return MP_MEMORY;
+
+			c->digits[max] = carry;
+			++uc;
+		}
+
+		MP_USED(c) = uc;
+		MP_SIGN(c) = MP_SIGN(a);
+
+	}
+	else
+	{
+		/* Different signs -- subtract magnitudes, preserve sign of greater */
+		mp_int		x,
+					y;
+		int			cmp = s_ucmp(a, b); /* magnitude comparison, sign ignored */
+
+		/* Set x to max(a, b), y to min(a, b) to simplify later code */
+		if (cmp >= 0)
+		{
+			x = a;
+			y = b;
+		}
+		else
+		{
+			x = b;
+			y = a;
+		}
+
+		if (!s_pad(c, MP_USED(x)))
+			return MP_MEMORY;
+
+		/* Subtract smaller from larger */
+		s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y));
+		MP_USED(c) = MP_USED(x);
+		CLAMP(c);
+
+		/* Give result the sign of the larger */
+		MP_SIGN(c) = MP_SIGN(x);
+	}
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_add_value(a, value, c) */
+
+mp_result
+mp_int_add_value(mp_int a, int value, mp_int c)
+{
+	mpz_t		vtmp;
+	mp_digit	vbuf[MP_VALUE_DIGITS(value)];
+
+	s_fake(&vtmp, value, vbuf);
+
+	return mp_int_add(a, &vtmp, c);
+}
+
+/* }}} */
+
+/* {{{ mp_int_sub(a, b, c) */
+
+mp_result
+mp_int_sub(mp_int a, mp_int b, mp_int c)
+{
+	mp_size		ua,
+				ub,
+				uc,
+				max;
+
+	CHECK(a != NULL && b != NULL && c != NULL);
+
+	ua = MP_USED(a);
+	ub = MP_USED(b);
+	uc = MP_USED(c);
+	max = MAX(ua, ub);
+
+	if (MP_SIGN(a) != MP_SIGN(b))
+	{
+		/* Different signs -- add magnitudes and keep sign of a */
+		mp_digit	carry;
+
+		if (!s_pad(c, max))
+			return MP_MEMORY;
+
+		carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub);
+		uc = max;
+
+		if (carry)
+		{
+			if (!s_pad(c, max + 1))
+				return MP_MEMORY;
+
+			c->digits[max] = carry;
+			++uc;
+		}
+
+		MP_USED(c) = uc;
+		MP_SIGN(c) = MP_SIGN(a);
+
+	}
+	else
+	{
+		/* Same signs -- subtract magnitudes */
+		mp_int		x,
+					y;
+		mp_sign		osign;
+		int			cmp = s_ucmp(a, b);
+
+		if (!s_pad(c, max))
+			return MP_MEMORY;
+
+		if (cmp >= 0)
+		{
+			x = a;
+			y = b;
+			osign = MP_ZPOS;
+		}
+		else
+		{
+			x = b;
+			y = a;
+			osign = MP_NEG;
+		}
+
+		if (MP_SIGN(a) == MP_NEG && cmp != 0)
+			osign = 1 - osign;
+
+		s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y));
+		MP_USED(c) = MP_USED(x);
+		CLAMP(c);
+
+		MP_SIGN(c) = osign;
+	}
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_sub_value(a, value, c) */
+
+mp_result
+mp_int_sub_value(mp_int a, int value, mp_int c)
+{
+	mpz_t		vtmp;
+	mp_digit	vbuf[MP_VALUE_DIGITS(value)];
+
+	s_fake(&vtmp, value, vbuf);
+
+	return mp_int_sub(a, &vtmp, c);
+}
+
+/* }}} */
+
+/* {{{ mp_int_mul(a, b, c) */
+
+mp_result
+mp_int_mul(mp_int a, mp_int b, mp_int c)
+{
+	mp_digit   *out;
+	mp_size		osize,
+				ua,
+				ub,
+				p = 0;
+	mp_sign		osign;
+
+	CHECK(a != NULL && b != NULL && c != NULL);
+
+	/* If either input is zero, we can shortcut multiplication */
+	if (mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0)
+	{
+		mp_int_zero(c);
+		return MP_OK;
+	}
+
+	/* Output is positive if inputs have same sign, otherwise negative */
+	osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG;
+
+	/*
+	 * If the output is not equal to any of the inputs, we'll write the
+	 * results there directly; otherwise, allocate a temporary space.
+	 */
+	ua = MP_USED(a);
+	ub = MP_USED(b);
+	osize = ua + ub;
+
+	if (c == a || c == b)
+	{
+		p = ROUND_PREC(osize);
+		p = MAX(p, default_precision);
+
+		if ((out = s_alloc(p)) == NULL)
+			return MP_MEMORY;
+	}
+	else
+	{
+		if (!s_pad(c, osize))
+			return MP_MEMORY;
+
+		out = MP_DIGITS(c);
+	}
+	ZERO(out, osize);
+
+	if (!s_kmul(MP_DIGITS(a), MP_DIGITS(b), out, ua, ub))
+		return MP_MEMORY;
+
+	/*
+	 * If we allocated a new buffer, get rid of whatever memory c was already
+	 * using, and fix up its fields to reflect that.
+	 */
+	if (out != MP_DIGITS(c))
+	{
+		s_free(MP_DIGITS(c));
+		MP_DIGITS(c) = out;
+		MP_ALLOC(c) = p;
+	}
+
+	MP_USED(c) = osize;			/* might not be true, but we'll fix it ... */
+	CLAMP(c);					/* ... right here */
+	MP_SIGN(c) = osign;
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_mul_value(a, value, c) */
+
+mp_result
+mp_int_mul_value(mp_int a, int value, mp_int c)
+{
+	mpz_t		vtmp;
+	mp_digit	vbuf[MP_VALUE_DIGITS(value)];
+
+	s_fake(&vtmp, value, vbuf);
+
+	return mp_int_mul(a, &vtmp, c);
+}
+
+/* }}} */
+
+/* {{{ mp_int_mul_pow2(a, p2, c) */
+
+mp_result
+mp_int_mul_pow2(mp_int a, int p2, mp_int c)
+{
+	mp_result	res;
+
+	CHECK(a != NULL && c != NULL && p2 >= 0);
+
+	if ((res = mp_int_copy(a, c)) != MP_OK)
+		return res;
+
+	if (s_qmul(c, (mp_size) p2))
+		return MP_OK;
+	else
+		return MP_MEMORY;
+}
+
+/* }}} */
+
+/* {{{ mp_int_sqr(a, c) */
+
+mp_result
+mp_int_sqr(mp_int a, mp_int c)
+{
+	mp_digit   *out;
+	mp_size		osize,
+				p = 0;
+
+	CHECK(a != NULL && c != NULL);
+
+	/* Get a temporary buffer big enough to hold the result */
+	osize = (mp_size) 2 *MP_USED(a);
+
+	if (a == c)
+	{
+		p = ROUND_PREC(osize);
+		p = MAX(p, default_precision);
+
+		if ((out = s_alloc(p)) == NULL)
+			return MP_MEMORY;
+	}
+	else
+	{
+		if (!s_pad(c, osize))
+			return MP_MEMORY;
+
+		out = MP_DIGITS(c);
+	}
+	ZERO(out, osize);
+
+	s_ksqr(MP_DIGITS(a), out, MP_USED(a));
+
+	/*
+	 * Get rid of whatever memory c was already using, and fix up its fields
+	 * to reflect the new digit array it's using
+	 */
+	if (out != MP_DIGITS(c))
+	{
+		s_free(MP_DIGITS(c));
+		MP_DIGITS(c) = out;
+		MP_ALLOC(c) = p;
+	}
+
+	MP_USED(c) = osize;			/* might not be true, but we'll fix it ... */
+	CLAMP(c);					/* ... right here */
+	MP_SIGN(c) = MP_ZPOS;
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_div(a, b, q, r) */
+
+mp_result
+mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r)
+{
+	int			cmp,
+				last = 0,
+				lg;
+	mp_result	res = MP_OK;
+	mpz_t		temp[2];
+	mp_int		qout,
+				rout;
+	mp_sign		sa = MP_SIGN(a),
+				sb = MP_SIGN(b);
+
+	CHECK(a != NULL && b != NULL && q != r);
+
+	if (CMPZ(b) == 0)
+		return MP_UNDEF;
+	else if ((cmp = s_ucmp(a, b)) < 0)
+	{
+		/*
+		 * If |a| < |b|, no division is required: q = 0, r = a
+		 */
+		if (r && (res = mp_int_copy(a, r)) != MP_OK)
+			return res;
+
+		if (q)
+			mp_int_zero(q);
+
+		return MP_OK;
+	}
+	else if (cmp == 0)
+	{
+		/*
+		 * If |a| = |b|, no division is required: q = 1 or -1, r = 0
+		 */
+		if (r)
+			mp_int_zero(r);
+
+		if (q)
+		{
+			mp_int_zero(q);
+			q->digits[0] = 1;
+
+			if (sa != sb)
+				MP_SIGN(q) = MP_NEG;
+		}
+
+		return MP_OK;
+	}
+
+	/*
+	 * When |a| > |b|, real division is required.  We need someplace to store
+	 * quotient and remainder, but q and r are allowed to be NULL or to
+	 * overlap with the inputs.
+	 */
+	if ((lg = s_isp2(b)) < 0)
+	{
+		if (q && b != q && (res = mp_int_copy(a, q)) == MP_OK)
+		{
+			qout = q;
+		}
+		else
+		{
+			qout = TEMP(last);
+			SETUP(mp_int_init_copy(TEMP(last), a), last);
+		}
+
+		if (r && a != r && (res = mp_int_copy(b, r)) == MP_OK)
+		{
+			rout = r;
+		}
+		else
+		{
+			rout = TEMP(last);
+			SETUP(mp_int_init_copy(TEMP(last), b), last);
+		}
+
+		if ((res = s_udiv(qout, rout)) != MP_OK)
+			goto CLEANUP;
+	}
+	else
+	{
+		if (q && (res = mp_int_copy(a, q)) != MP_OK)
+			goto CLEANUP;
+		if (r && (res = mp_int_copy(a, r)) != MP_OK)
+			goto CLEANUP;
+
+		if (q)
+			s_qdiv(q, (mp_size) lg);
+		qout = q;
+		if (r)
+			s_qmod(r, (mp_size) lg);
+		rout = r;
+	}
+
+	/* Recompute signs for output */
+	if (rout)
+	{
+		MP_SIGN(rout) = sa;
+		if (CMPZ(rout) == 0)
+			MP_SIGN(rout) = MP_ZPOS;
+	}
+	if (qout)
+	{
+		MP_SIGN(qout) = (sa == sb) ? MP_ZPOS : MP_NEG;
+		if (CMPZ(qout) == 0)
+			MP_SIGN(qout) = MP_ZPOS;
+	}
+
+	if (q && (res = mp_int_copy(qout, q)) != MP_OK)
+		goto CLEANUP;
+	if (r && (res = mp_int_copy(rout, r)) != MP_OK)
+		goto CLEANUP;
+
+CLEANUP:
+	while (--last >= 0)
+		mp_int_clear(TEMP(last));
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_mod(a, m, c) */
+
+mp_result
+mp_int_mod(mp_int a, mp_int m, mp_int c)
+{
+	mp_result	res;
+	mpz_t		tmp;
+	mp_int		out;
+
+	if (m == c)
+	{
+		if ((res = mp_int_init(&tmp)) != MP_OK)
+			return res;
+
+		out = &tmp;
+	}
+	else
+	{
+		out = c;
+	}
+
+	if ((res = mp_int_div(a, m, NULL, out)) != MP_OK)
+		goto CLEANUP;
+
+	if (CMPZ(out) < 0)
+		res = mp_int_add(out, m, c);
+	else
+		res = mp_int_copy(out, c);
+
+CLEANUP:
+	if (out != c)
+		mp_int_clear(&tmp);
+
+	return res;
+}
+
+/* }}} */
+
+
+/* {{{ mp_int_div_value(a, value, q, r) */
+
+mp_result
+mp_int_div_value(mp_int a, int value, mp_int q, int *r)
+{
+	mpz_t		vtmp,
+				rtmp;
+	mp_digit	vbuf[MP_VALUE_DIGITS(value)];
+	mp_result	res;
+
+	if ((res = mp_int_init(&rtmp)) != MP_OK)
+		return res;
+	s_fake(&vtmp, value, vbuf);
+
+	if ((res = mp_int_div(a, &vtmp, q, &rtmp)) != MP_OK)
+		goto CLEANUP;
+
+	if (r)
+		(void) mp_int_to_int(&rtmp, r); /* can't fail */
+
+CLEANUP:
+	mp_int_clear(&rtmp);
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_div_pow2(a, p2, q, r) */
+
+mp_result
+mp_int_div_pow2(mp_int a, int p2, mp_int q, mp_int r)
+{
+	mp_result	res = MP_OK;
+
+	CHECK(a != NULL && p2 >= 0 && q != r);
+
+	if (q != NULL && (res = mp_int_copy(a, q)) == MP_OK)
+		s_qdiv(q, (mp_size) p2);
+
+	if (res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK)
+		s_qmod(r, (mp_size) p2);
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_expt(a, b, c) */
+
+mp_result
+mp_int_expt(mp_int a, int b, mp_int c)
+{
+	mpz_t		t;
+	mp_result	res;
+	unsigned int v = abs(b);
+
+	CHECK(b >= 0 && c != NULL);
+
+	if ((res = mp_int_init_copy(&t, a)) != MP_OK)
+		return res;
+
+	(void) mp_int_set_value(c, 1);
+	while (v != 0)
+	{
+		if (v & 1)
+		{
+			if ((res = mp_int_mul(c, &t, c)) != MP_OK)
+				goto CLEANUP;
+		}
+
+		v >>= 1;
+		if (v == 0)
+			break;
+
+		if ((res = mp_int_sqr(&t, &t)) != MP_OK)
+			goto CLEANUP;
+	}
+
+CLEANUP:
+	mp_int_clear(&t);
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_expt_value(a, b, c) */
+
+mp_result
+mp_int_expt_value(int a, int b, mp_int c)
+{
+	mpz_t		t;
+	mp_result	res;
+	unsigned int v = abs(b);
+
+	CHECK(b >= 0 && c != NULL);
+
+	if ((res = mp_int_init_value(&t, a)) != MP_OK)
+		return res;
+
+	(void) mp_int_set_value(c, 1);
+	while (v != 0)
+	{
+		if (v & 1)
+		{
+			if ((res = mp_int_mul(c, &t, c)) != MP_OK)
+				goto CLEANUP;
+		}
+
+		v >>= 1;
+		if (v == 0)
+			break;
+
+		if ((res = mp_int_sqr(&t, &t)) != MP_OK)
+			goto CLEANUP;
+	}
+
+CLEANUP:
+	mp_int_clear(&t);
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_compare(a, b) */
+
+int
+mp_int_compare(mp_int a, mp_int b)
+{
+	mp_sign		sa;
+
+	CHECK(a != NULL && b != NULL);
+
+	sa = MP_SIGN(a);
+	if (sa == MP_SIGN(b))
+	{
+		int			cmp = s_ucmp(a, b);
+
+		/*
+		 * If they're both zero or positive, the normal comparison applies; if
+		 * both negative, the sense is reversed.
+		 */
+		if (sa == MP_ZPOS)
+			return cmp;
+		else
+			return -cmp;
+
+	}
+	else
+	{
+		if (sa == MP_ZPOS)
+			return 1;
+		else
+			return -1;
+	}
+}
+
+/* }}} */
+
+/* {{{ mp_int_compare_unsigned(a, b) */
+
+int
+mp_int_compare_unsigned(mp_int a, mp_int b)
+{
+	NRCHECK(a != NULL && b != NULL);
+
+	return s_ucmp(a, b);
+}
+
+/* }}} */
+
+/* {{{ mp_int_compare_zero(z) */
+
+int
+mp_int_compare_zero(mp_int z)
+{
+	NRCHECK(z != NULL);
+
+	if (MP_USED(z) == 1 && z->digits[0] == 0)
+		return 0;
+	else if (MP_SIGN(z) == MP_ZPOS)
+		return 1;
+	else
+		return -1;
+}
+
+/* }}} */
+
+/* {{{ mp_int_compare_value(z, value) */
+
+int
+mp_int_compare_value(mp_int z, int value)
+{
+	mp_sign		vsign = (value < 0) ? MP_NEG : MP_ZPOS;
+	int			cmp;
+
+	CHECK(z != NULL);
+
+	if (vsign == MP_SIGN(z))
+	{
+		cmp = s_vcmp(z, value);
+
+		if (vsign == MP_ZPOS)
+			return cmp;
+		else
+			return -cmp;
+	}
+	else
+	{
+		if (value < 0)
+			return 1;
+		else
+			return -1;
+	}
+}
+
+/* }}} */
+
+/* {{{ mp_int_exptmod(a, b, m, c) */
+
+mp_result
+mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c)
+{
+	mp_result	res;
+	mp_size		um;
+	mpz_t		temp[3];
+	mp_int		s;
+	int			last = 0;
+
+	CHECK(a != NULL && b != NULL && c != NULL && m != NULL);
+
+	/* Zero moduli and negative exponents are not considered. */
+	if (CMPZ(m) == 0)
+		return MP_UNDEF;
+	if (CMPZ(b) < 0)
+		return MP_RANGE;
+
+	um = MP_USED(m);
+	SETUP(mp_int_init_size(TEMP(0), 2 * um), last);
+	SETUP(mp_int_init_size(TEMP(1), 2 * um), last);
+
+	if (c == b || c == m)
+	{
+		SETUP(mp_int_init_size(TEMP(2), 2 * um), last);
+		s = TEMP(2);
+	}
+	else
+	{
+		s = c;
+	}
+
+	if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK)
+		goto CLEANUP;
+
+	if ((res = s_brmu(TEMP(1), m)) != MP_OK)
+		goto CLEANUP;
+
+	if ((res = s_embar(TEMP(0), b, m, TEMP(1), s)) != MP_OK)
+		goto CLEANUP;
+
+	res = mp_int_copy(s, c);
+
+CLEANUP:
+	while (--last >= 0)
+		mp_int_clear(TEMP(last));
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_exptmod_evalue(a, value, m, c) */
+
+mp_result
+mp_int_exptmod_evalue(mp_int a, int value, mp_int m, mp_int c)
+{
+	mpz_t		vtmp;
+	mp_digit	vbuf[MP_VALUE_DIGITS(value)];
+
+	s_fake(&vtmp, value, vbuf);
+
+	return mp_int_exptmod(a, &vtmp, m, c);
+}
+
+/* }}} */
+
+/* {{{ mp_int_exptmod_bvalue(v, b, m, c) */
+
+mp_result
+mp_int_exptmod_bvalue(int value, mp_int b,
+					  mp_int m, mp_int c)
+{
+	mpz_t		vtmp;
+	mp_digit	vbuf[MP_VALUE_DIGITS(value)];
+
+	s_fake(&vtmp, value, vbuf);
+
+	return mp_int_exptmod(&vtmp, b, m, c);
+}
+
+/* }}} */
+
+/* {{{ mp_int_exptmod_known(a, b, m, mu, c) */
+
+mp_result
+mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
+{
+	mp_result	res;
+	mp_size		um;
+	mpz_t		temp[2];
+	mp_int		s;
+	int			last = 0;
+
+	CHECK(a && b && m && c);
+
+	/* Zero moduli and negative exponents are not considered. */
+	if (CMPZ(m) == 0)
+		return MP_UNDEF;
+	if (CMPZ(b) < 0)
+		return MP_RANGE;
+
+	um = MP_USED(m);
+	SETUP(mp_int_init_size(TEMP(0), 2 * um), last);
+
+	if (c == b || c == m)
+	{
+		SETUP(mp_int_init_size(TEMP(1), 2 * um), last);
+		s = TEMP(1);
+	}
+	else
+	{
+		s = c;
+	}
+
+	if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK)
+		goto CLEANUP;
+
+	if ((res = s_embar(TEMP(0), b, m, mu, s)) != MP_OK)
+		goto CLEANUP;
+
+	res = mp_int_copy(s, c);
+
+CLEANUP:
+	while (--last >= 0)
+		mp_int_clear(TEMP(last));
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_redux_const(m, c) */
+
+mp_result
+mp_int_redux_const(mp_int m, mp_int c)
+{
+	CHECK(m != NULL && c != NULL && m != c);
+
+	return s_brmu(c, m);
+}
+
+/* }}} */
+
+/* {{{ mp_int_invmod(a, m, c) */
+
+mp_result
+mp_int_invmod(mp_int a, mp_int m, mp_int c)
+{
+	mp_result	res;
+	mp_sign		sa;
+	int			last = 0;
+	mpz_t		temp[2];
+
+	CHECK(a != NULL && m != NULL && c != NULL);
+
+	if (CMPZ(a) == 0 || CMPZ(m) <= 0)
+		return MP_RANGE;
+
+	sa = MP_SIGN(a);			/* need this for the result later */
+
+	for (last = 0; last < 2; ++last)
+		if ((res = mp_int_init(TEMP(last))) != MP_OK)
+			goto CLEANUP;
+
+	if ((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK)
+		goto CLEANUP;
+
+	if (mp_int_compare_value(TEMP(0), 1) != 0)
+	{
+		res = MP_UNDEF;
+		goto CLEANUP;
+	}
+
+	/* It is first necessary to constrain the value to the proper range */
+	if ((res = mp_int_mod(TEMP(1), m, TEMP(1))) != MP_OK)
+		goto CLEANUP;
+
+	/*
+	 * Now, if 'a' was originally negative, the value we have is actually the
+	 * magnitude of the negative representative; to get the positive value we
+	 * have to subtract from the modulus.  Otherwise, the value is okay as it
+	 * stands.
+	 */
+	if (sa == MP_NEG)
+		res = mp_int_sub(m, TEMP(1), c);
+	else
+		res = mp_int_copy(TEMP(1), c);
+
+CLEANUP:
+	while (--last >= 0)
+		mp_int_clear(TEMP(last));
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_gcd(a, b, c) */
+
+/* Binary GCD algorithm due to Josef Stein, 1961 */
+mp_result
+mp_int_gcd(mp_int a, mp_int b, mp_int c)
+{
+	int			ca,
+				cb,
+				k = 0;
+	mpz_t		u,
+				v,
+				t;
+	mp_result	res;
+
+	CHECK(a != NULL && b != NULL && c != NULL);
+
+	ca = CMPZ(a);
+	cb = CMPZ(b);
+	if (ca == 0 && cb == 0)
+		return MP_UNDEF;
+	else if (ca == 0)
+		return mp_int_abs(b, c);
+	else if (cb == 0)
+		return mp_int_abs(a, c);
+
+	if ((res = mp_int_init(&t)) != MP_OK)
+		return res;
+	if ((res = mp_int_init_copy(&u, a)) != MP_OK)
+		goto U;
+	if ((res = mp_int_init_copy(&v, b)) != MP_OK)
+		goto V;
+
+	MP_SIGN(&u) = MP_ZPOS;
+	MP_SIGN(&v) = MP_ZPOS;
+
+	{							/* Divide out common factors of 2 from u and v */
+		int			div2_u = s_dp2k(&u),
+					div2_v = s_dp2k(&v);
+
+		k = MIN(div2_u, div2_v);
+		s_qdiv(&u, (mp_size) k);
+		s_qdiv(&v, (mp_size) k);
+	}
+
+	if (mp_int_is_odd(&u))
+	{
+		if ((res = mp_int_neg(&v, &t)) != MP_OK)
+			goto CLEANUP;
+	}
+	else
+	{
+		if ((res = mp_int_copy(&u, &t)) != MP_OK)
+			goto CLEANUP;
+	}
+
+	for (;;)
+	{
+		s_qdiv(&t, s_dp2k(&t));
+
+		if (CMPZ(&t) > 0)
+		{
+			if ((res = mp_int_copy(&t, &u)) != MP_OK)
+				goto CLEANUP;
+		}
+		else
+		{
+			if ((res = mp_int_neg(&t, &v)) != MP_OK)
+				goto CLEANUP;
+		}
+
+		if ((res = mp_int_sub(&u, &v, &t)) != MP_OK)
+			goto CLEANUP;
+
+		if (CMPZ(&t) == 0)
+			break;
+	}
+
+	if ((res = mp_int_abs(&u, c)) != MP_OK)
+		goto CLEANUP;
+	if (!s_qmul(c, (mp_size) k))
+		res = MP_MEMORY;
+
+CLEANUP:
+	mp_int_clear(&v);
+V: mp_int_clear(&u);
+U: mp_int_clear(&t);
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_egcd(a, b, c, x, y) */
+
+/* This is the binary GCD algorithm again, but this time we keep track
+   of the elementary matrix operations as we go, so we can get values
+   x and y satisfying c = ax + by.
+ */
+mp_result
+mp_int_egcd(mp_int a, mp_int b, mp_int c,
+			mp_int x, mp_int y)
+{
+	int			k,
+				last = 0,
+				ca,
+				cb;
+	mpz_t		temp[8];
+	mp_result	res;
+
+	CHECK(a != NULL && b != NULL && c != NULL &&
+		  (x != NULL || y != NULL));
+
+	ca = CMPZ(a);
+	cb = CMPZ(b);
+	if (ca == 0 && cb == 0)
+		return MP_UNDEF;
+	else if (ca == 0)
+	{
+		if ((res = mp_int_abs(b, c)) != MP_OK)
+			return res;
+		mp_int_zero(x);
+		(void) mp_int_set_value(y, 1);
+		return MP_OK;
+	}
+	else if (cb == 0)
+	{
+		if ((res = mp_int_abs(a, c)) != MP_OK)
+			return res;
+		(void) mp_int_set_value(x, 1);
+		mp_int_zero(y);
+		return MP_OK;
+	}
+
+	/*
+	 * Initialize temporaries: A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7
+	 */
+	for (last = 0; last < 4; ++last)
+	{
+		if ((res = mp_int_init(TEMP(last))) != MP_OK)
+			goto CLEANUP;
+	}
+	TEMP(0)->digits[0] = 1;
+	TEMP(3)->digits[0] = 1;
+
+	SETUP(mp_int_init_copy(TEMP(4), a), last);
+	SETUP(mp_int_init_copy(TEMP(5), b), last);
+
+	/* We will work with absolute values here */
+	MP_SIGN(TEMP(4)) = MP_ZPOS;
+	MP_SIGN(TEMP(5)) = MP_ZPOS;
+
+	{							/* Divide out common factors of 2 from u and v */
+		int			div2_u = s_dp2k(TEMP(4)),
+					div2_v = s_dp2k(TEMP(5));
+
+		k = MIN(div2_u, div2_v);
+		s_qdiv(TEMP(4), k);
+		s_qdiv(TEMP(5), k);
+	}
+
+	SETUP(mp_int_init_copy(TEMP(6), TEMP(4)), last);
+	SETUP(mp_int_init_copy(TEMP(7), TEMP(5)), last);
+
+	for (;;)
+	{
+		while (mp_int_is_even(TEMP(4)))
+		{
+			s_qdiv(TEMP(4), 1);
+
+			if (mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1)))
+			{
+				if ((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK)
+					goto CLEANUP;
+				if ((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK)
+					goto CLEANUP;
+			}
+
+			s_qdiv(TEMP(0), 1);
+			s_qdiv(TEMP(1), 1);
+		}
+
+		while (mp_int_is_even(TEMP(5)))
+		{
+			s_qdiv(TEMP(5), 1);
+
+			if (mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3)))
+			{
+				if ((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK)
+					goto CLEANUP;
+				if ((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK)
+					goto CLEANUP;
+			}
+
+			s_qdiv(TEMP(2), 1);
+			s_qdiv(TEMP(3), 1);
+		}
+
+		if (mp_int_compare(TEMP(4), TEMP(5)) >= 0)
+		{
+			if ((res = mp_int_sub(TEMP(4), TEMP(5), TEMP(4))) != MP_OK)
+				goto CLEANUP;
+			if ((res = mp_int_sub(TEMP(0), TEMP(2), TEMP(0))) != MP_OK)
+				goto CLEANUP;
+			if ((res = mp_int_sub(TEMP(1), TEMP(3), TEMP(1))) != MP_OK)
+				goto CLEANUP;
+		}
+		else
+		{
+			if ((res = mp_int_sub(TEMP(5), TEMP(4), TEMP(5))) != MP_OK)
+				goto CLEANUP;
+			if ((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK)
+				goto CLEANUP;
+			if ((res = mp_int_sub(TEMP(3), TEMP(1), TEMP(3))) != MP_OK)
+				goto CLEANUP;
+		}
+
+		if (CMPZ(TEMP(4)) == 0)
+		{
+			if (x && (res = mp_int_copy(TEMP(2), x)) != MP_OK)
+				goto CLEANUP;
+			if (y && (res = mp_int_copy(TEMP(3), y)) != MP_OK)
+				goto CLEANUP;
+			if (c)
+			{
+				if (!s_qmul(TEMP(5), k))
+				{
+					res = MP_MEMORY;
+					goto CLEANUP;
+				}
+
+				res = mp_int_copy(TEMP(5), c);
+			}
+
+			break;
+		}
+	}
+
+CLEANUP:
+	while (--last >= 0)
+		mp_int_clear(TEMP(last));
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_divisible_value(a, v) */
+
+int
+mp_int_divisible_value(mp_int a, int v)
+{
+	int			rem = 0;
+
+	if (mp_int_div_value(a, v, NULL, &rem) != MP_OK)
+		return 0;
+
+	return rem == 0;
+}
+
+/* }}} */
+
+/* {{{ mp_int_is_pow2(z) */
+
+int
+mp_int_is_pow2(mp_int z)
+{
+	CHECK(z != NULL);
+
+	return s_isp2(z);
+}
+
+/* }}} */
+
+/* {{{ mp_int_sqrt(a, c) */
+
+mp_result
+mp_int_sqrt(mp_int a, mp_int c)
+{
+	mp_result	res = MP_OK;
+	mpz_t		temp[2];
+	int			last = 0;
+
+	CHECK(a != NULL && c != NULL);
+
+	/* The square root of a negative value does not exist in the integers. */
+	if (MP_SIGN(a) == MP_NEG)
+		return MP_UNDEF;
+
+	SETUP(mp_int_init_copy(TEMP(last), a), last);
+	SETUP(mp_int_init(TEMP(last)), last);
+
+	for (;;)
+	{
+		if ((res = mp_int_sqr(TEMP(0), TEMP(1))) != MP_OK)
+			goto CLEANUP;
+
+		if (mp_int_compare_unsigned(a, TEMP(1)) == 0)
+			break;
+
+		if ((res = mp_int_copy(a, TEMP(1))) != MP_OK)
+			goto CLEANUP;
+		if ((res = mp_int_div(TEMP(1), TEMP(0), TEMP(1), NULL)) != MP_OK)
+			goto CLEANUP;
+		if ((res = mp_int_add(TEMP(0), TEMP(1), TEMP(1))) != MP_OK)
+			goto CLEANUP;
+		if ((res = mp_int_div_pow2(TEMP(1), 1, TEMP(1), NULL)) != MP_OK)
+			goto CLEANUP;
+
+		if (mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0)
+			break;
+		if ((res = mp_int_sub_value(TEMP(0), 1, TEMP(0))) != MP_OK)
+			goto CLEANUP;
+		if (mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0)
+			break;
+
+		if ((res = mp_int_copy(TEMP(1), TEMP(0))) != MP_OK)
+			goto CLEANUP;
+	}
+
+	res = mp_int_copy(TEMP(0), c);
+
+CLEANUP:
+	while (--last >= 0)
+		mp_int_clear(TEMP(last));
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_to_int(z, out) */
+
+mp_result
+mp_int_to_int(mp_int z, int *out)
+{
+	unsigned int uv = 0;
+	mp_size		uz;
+	mp_digit   *dz;
+	mp_sign		sz;
+
+	CHECK(z != NULL);
+
+	/* Make sure the value is representable as an int */
+	sz = MP_SIGN(z);
+	if ((sz == MP_ZPOS && mp_int_compare_value(z, INT_MAX) > 0) ||
+		mp_int_compare_value(z, INT_MIN) < 0)
+		return MP_RANGE;
+
+	uz = MP_USED(z);
+	dz = MP_DIGITS(z) + uz - 1;
+
+	while (uz > 0)
+	{
+		uv <<= MP_DIGIT_BIT / 2;
+		uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--;
+		--uz;
+	}
+
+	if (out)
+		*out = (sz == MP_NEG) ? -(int) uv : (int) uv;
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_to_string(z, radix, str, limit) */
+
+mp_result
+mp_int_to_string(mp_int z, mp_size radix,
+				 char *str, int limit)
+{
+	mp_result	res;
+	int			cmp = 0;
+
+	CHECK(z != NULL && str != NULL && limit >= 2);
+
+	if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
+		return MP_RANGE;
+
+	if (CMPZ(z) == 0)
+	{
+		*str++ = s_val2ch(0, mp_flags & MP_CAP_DIGITS);
+	}
+	else
+	{
+		mpz_t		tmp;
+		char	   *h,
+				   *t;
+
+		if ((res = mp_int_init_copy(&tmp, z)) != MP_OK)
+			return res;
+
+		if (MP_SIGN(z) == MP_NEG)
+		{
+			*str++ = '-';
+			--limit;
+		}
+		h = str;
+
+		/* Generate digits in reverse order until finished or limit reached */
+		for ( /* */ ; limit > 0; --limit)
+		{
+			mp_digit	d;
+
+			if ((cmp = CMPZ(&tmp)) == 0)
+				break;
+
+			d = s_ddiv(&tmp, (mp_digit) radix);
+			*str++ = s_val2ch(d, mp_flags & MP_CAP_DIGITS);
+		}
+		t = str - 1;
+
+		/* Put digits back in correct output order */
+		while (h < t)
+		{
+			char		tc = *h;
+
+			*h++ = *t;
+			*t-- = tc;
+		}
+
+		mp_int_clear(&tmp);
+	}
+
+	*str = '\0';
+	if (cmp == 0)
+		return MP_OK;
+	else
+		return MP_TRUNC;
+}
+
+/* }}} */
+
+/* {{{ mp_int_string_len(z, radix) */
+
+mp_result
+mp_int_string_len(mp_int z, mp_size radix)
+{
+	int			len;
+
+	CHECK(z != NULL);
+
+	if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
+		return MP_RANGE;
+
+	len = s_outlen(z, radix) + 1;		/* for terminator */
+
+	/* Allow for sign marker on negatives */
+	if (MP_SIGN(z) == MP_NEG)
+		len += 1;
+
+	return len;
+}
+
+/* }}} */
+
+/* {{{ mp_int_read_string(z, radix, *str) */
+
+/* Read zero-terminated string into z */
+mp_result
+mp_int_read_string(mp_int z, mp_size radix, const char *str)
+{
+	return mp_int_read_cstring(z, radix, str, NULL);
+
+}
+
+/* }}} */
+
+/* {{{ mp_int_read_cstring(z, radix, *str, **end) */
+
+mp_result
+mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end)
+{
+	int			ch;
+
+	CHECK(z != NULL && str != NULL);
+
+	if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX)
+		return MP_RANGE;
+
+	/* Skip leading whitespace */
+	while (isspace((unsigned char) *str))
+		++str;
+
+	/* Handle leading sign tag (+/-, positive default) */
+	switch (*str)
+	{
+		case '-':
+			MP_SIGN(z) = MP_NEG;
+			++str;
+			break;
+		case '+':
+			++str;				/* fallthrough */
+		default:
+			MP_SIGN(z) = MP_ZPOS;
+			break;
+	}
+
+	/* Skip leading zeroes */
+	while ((ch = s_ch2val(*str, radix)) == 0)
+		++str;
+
+	/* Make sure there is enough space for the value */
+	if (!s_pad(z, s_inlen(strlen(str), radix)))
+		return MP_MEMORY;
+
+	MP_USED(z) = 1;
+	z->digits[0] = 0;
+
+	while (*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0))
+	{
+		s_dmul(z, (mp_digit) radix);
+		s_dadd(z, (mp_digit) ch);
+		++str;
+	}
+
+	CLAMP(z);
+
+	/* Override sign for zero, even if negative specified. */
+	if (CMPZ(z) == 0)
+		MP_SIGN(z) = MP_ZPOS;
+
+	if (end != NULL)
+		*end = (char *) str;
+
+	/*
+	 * Return a truncation error if the string has unprocessed characters
+	 * remaining, so the caller can tell if the whole string was done
+	 */
+	if (*str != '\0')
+		return MP_TRUNC;
+	else
+		return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_count_bits(z) */
+
+mp_result
+mp_int_count_bits(mp_int z)
+{
+	mp_size		nbits = 0,
+				uz;
+	mp_digit	d;
+
+	CHECK(z != NULL);
+
+	uz = MP_USED(z);
+	if (uz == 1 && z->digits[0] == 0)
+		return 1;
+
+	--uz;
+	nbits = uz * MP_DIGIT_BIT;
+	d = z->digits[uz];
+
+	while (d != 0)
+	{
+		d >>= 1;
+		++nbits;
+	}
+
+	return nbits;
+}
+
+/* }}} */
+
+/* {{{ mp_int_to_binary(z, buf, limit) */
+
+mp_result
+mp_int_to_binary(mp_int z, unsigned char *buf, int limit)
+{
+	static const int PAD_FOR_2C = 1;
+
+	mp_result	res;
+	int			limpos = limit;
+
+	CHECK(z != NULL && buf != NULL);
+
+	res = s_tobin(z, buf, &limpos, PAD_FOR_2C);
+
+	if (MP_SIGN(z) == MP_NEG)
+		s_2comp(buf, limpos);
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ mp_int_read_binary(z, buf, len) */
+
+mp_result
+mp_int_read_binary(mp_int z, unsigned char *buf, int len)
+{
+	mp_size		need,
+				i;
+	unsigned char *tmp;
+	mp_digit   *dz;
+
+	CHECK(z != NULL && buf != NULL && len > 0);
+
+	/* Figure out how many digits are needed to represent this value */
+	need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
+	if (!s_pad(z, need))
+		return MP_MEMORY;
+
+	mp_int_zero(z);
+
+	/*
+	 * If the high-order bit is set, take the 2's complement before reading
+	 * the value (it will be restored afterward)
+	 */
+	if (buf[0] >> (CHAR_BIT - 1))
+	{
+		MP_SIGN(z) = MP_NEG;
+		s_2comp(buf, len);
+	}
+
+	dz = MP_DIGITS(z);
+	for (tmp = buf, i = len; i > 0; --i, ++tmp)
+	{
+		s_qmul(z, (mp_size) CHAR_BIT);
+		*dz |= *tmp;
+	}
+
+	/* Restore 2's complement if we took it before */
+	if (MP_SIGN(z) == MP_NEG)
+		s_2comp(buf, len);
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_binary_len(z) */
+
+mp_result
+mp_int_binary_len(mp_int z)
+{
+	mp_result	res = mp_int_count_bits(z);
+	int			bytes = mp_int_unsigned_len(z);
+
+	if (res <= 0)
+		return res;
+
+	bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT;
+
+	/*
+	 * If the highest-order bit falls exactly on a byte boundary, we need to
+	 * pad with an extra byte so that the sign will be read correctly when
+	 * reading it back in.
+	 */
+	if (bytes * CHAR_BIT == res)
+		++bytes;
+
+	return bytes;
+}
+
+/* }}} */
+
+/* {{{ mp_int_to_unsigned(z, buf, limit) */
+
+mp_result
+mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit)
+{
+	static const int NO_PADDING = 0;
+
+	CHECK(z != NULL && buf != NULL);
+
+	return s_tobin(z, buf, &limit, NO_PADDING);
+}
+
+/* }}} */
+
+/* {{{ mp_int_read_unsigned(z, buf, len) */
+
+mp_result
+mp_int_read_unsigned(mp_int z, unsigned char *buf, int len)
+{
+	mp_size		need,
+				i;
+	unsigned char *tmp;
+	mp_digit   *dz;
+
+	CHECK(z != NULL && buf != NULL && len > 0);
+
+	/* Figure out how many digits are needed to represent this value */
+	need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT;
+	if (!s_pad(z, need))
+		return MP_MEMORY;
+
+	mp_int_zero(z);
+
+	dz = MP_DIGITS(z);
+	for (tmp = buf, i = len; i > 0; --i, ++tmp)
+	{
+		(void) s_qmul(z, CHAR_BIT);
+		*dz |= *tmp;
+	}
+
+	return MP_OK;
+}
+
+/* }}} */
+
+/* {{{ mp_int_unsigned_len(z) */
+
+mp_result
+mp_int_unsigned_len(mp_int z)
+{
+	mp_result	res = mp_int_count_bits(z);
+	int			bytes;
+
+	if (res <= 0)
+		return res;
+
+	bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT;
+
+	return bytes;
+}
+
+/* }}} */
+
+/* {{{ mp_error_string(res) */
+
+const char *
+mp_error_string(mp_result res)
+{
+	int			ix;
+
+	if (res > 0)
+		return s_unknown_err;
+
+	res = -res;
+	for (ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix)
+		;
+
+	if (s_error_msg[ix] != NULL)
+		return s_error_msg[ix];
+	else
+		return s_unknown_err;
+}
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* Private functions for internal use.	These make assumptions.			  */
+
+/* {{{ s_alloc(num) */
+
+static mp_digit *
+s_alloc(mp_size num)
+{
+	mp_digit   *out = px_alloc(num * sizeof(mp_digit));
+
+	assert(out != NULL);		/* for debugging */
+
+	return out;
+}
+
+/* }}} */
+
+/* {{{ s_realloc(old, num) */
+
+static mp_digit *
+s_realloc(mp_digit *old, mp_size num)
+{
+	mp_digit   *new = px_realloc(old, num * sizeof(mp_digit));
+
+	assert(new != NULL);		/* for debugging */
+
+	return new;
+}
+
+/* }}} */
+
+/* {{{ s_free(ptr) */
+
+#if TRACEABLE_FREE
+static void
+s_free(void *ptr)
+{
+	px_free(ptr);
+}
+#endif
+
+/* }}} */
+
+/* {{{ s_pad(z, min) */
+
+static int
+s_pad(mp_int z, mp_size min)
+{
+	if (MP_ALLOC(z) < min)
+	{
+		mp_size		nsize = ROUND_PREC(min);
+		mp_digit   *tmp = s_realloc(MP_DIGITS(z), nsize);
+
+		if (tmp == NULL)
+			return 0;
+
+		MP_DIGITS(z) = tmp;
+		MP_ALLOC(z) = nsize;
+	}
+
+	return 1;
+}
+
+/* }}} */
+
+/* {{{ s_clamp(z) */
+
+#if TRACEABLE_CLAMP
+static void
+s_clamp(mp_int z)
+{
+	mp_size		uz = MP_USED(z);
+	mp_digit   *zd = MP_DIGITS(z) + uz - 1;
+
+	while (uz > 1 && (*zd-- == 0))
+		--uz;
+
+	MP_USED(z) = uz;
+}
+#endif
+
+/* }}} */
+
+/* {{{ s_fake(z, value, vbuf) */
+
+static void
+s_fake(mp_int z, int value, mp_digit vbuf[])
+{
+	mp_size		uv = (mp_size) s_vpack(value, vbuf);
+
+	z->used = uv;
+	z->alloc = MP_VALUE_DIGITS(value);
+	z->sign = (value < 0) ? MP_NEG : MP_ZPOS;
+	z->digits = vbuf;
+}
+
+/* }}} */
+
+/* {{{ s_cdig(da, db, len) */
+
+static int
+s_cdig(mp_digit *da, mp_digit *db, mp_size len)
+{
+	mp_digit   *dat = da + len - 1,
+			   *dbt = db + len - 1;
+
+	for ( /* */ ; len != 0; --len, --dat, --dbt)
+	{
+		if (*dat > *dbt)
+			return 1;
+		else if (*dat < *dbt)
+			return -1;
+	}
+
+	return 0;
+}
+
+/* }}} */
+
+/* {{{ s_vpack(v, t[]) */
+
+static int
+s_vpack(int v, mp_digit t[])
+{
+	unsigned int uv = (unsigned int) ((v < 0) ? -v : v);
+	int			ndig = 0;
+
+	if (uv == 0)
+		t[ndig++] = 0;
+	else
+	{
+		while (uv != 0)
+		{
+			t[ndig++] = (mp_digit) uv;
+			uv >>= MP_DIGIT_BIT / 2;
+			uv >>= MP_DIGIT_BIT / 2;
+		}
+	}
+
+	return ndig;
+}
+
+/* }}} */
+
+/* {{{ s_ucmp(a, b) */
+
+static int
+s_ucmp(mp_int a, mp_int b)
+{
+	mp_size		ua = MP_USED(a),
+				ub = MP_USED(b);
+
+	if (ua > ub)
+		return 1;
+	else if (ub > ua)
+		return -1;
+	else
+		return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua);
+}
+
+/* }}} */
+
+/* {{{ s_vcmp(a, v) */
+
+static int
+s_vcmp(mp_int a, int v)
+{
+	mp_digit	vdig[MP_VALUE_DIGITS(v)];
+	int			ndig = 0;
+	mp_size		ua = MP_USED(a);
+
+	ndig = s_vpack(v, vdig);
+
+	if (ua > ndig)
+		return 1;
+	else if (ua < ndig)
+		return -1;
+	else
+		return s_cdig(MP_DIGITS(a), vdig, ndig);
+}
+
+/* }}} */
+
+/* {{{ s_uadd(da, db, dc, size_a, size_b) */
+
+static mp_digit
+s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b)
+{
+	mp_size		pos;
+	mp_word		w = 0;
+
+	/* Insure that da is the longer of the two to simplify later code */
+	if (size_b > size_a)
+	{
+		SWAP(mp_digit *, da, db);
+		SWAP(mp_size, size_a, size_b);
+	}
+
+	/* Add corresponding digits until the shorter number runs out */
+	for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc)
+	{
+		w = w + (mp_word) *da + (mp_word) *db;
+		*dc = LOWER_HALF(w);
+		w = UPPER_HALF(w);
+	}
+
+	/* Propagate carries as far as necessary */
+	for ( /* */ ; pos < size_a; ++pos, ++da, ++dc)
+	{
+		w = w + *da;
+
+		*dc = LOWER_HALF(w);
+		w = UPPER_HALF(w);
+	}
+
+	/* Return carry out */
+	return (mp_digit) w;
+}
+
+/* }}} */
+
+/* {{{ s_usub(da, db, dc, size_a, size_b) */
+
+static void
+s_usub(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b)
+{
+	mp_size		pos;
+	mp_word		w = 0;
+
+	/* We assume that |a| >= |b| so this should definitely hold */
+	assert(size_a >= size_b);
+
+	/* Subtract corresponding digits and propagate borrow */
+	for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc)
+	{
+		w = ((mp_word) MP_DIGIT_MAX + 1 +		/* MP_RADIX */
+			 (mp_word) *da) - w - (mp_word) *db;
+
+		*dc = LOWER_HALF(w);
+		w = (UPPER_HALF(w) == 0);
+	}
+
+	/* Finish the subtraction for remaining upper digits of da */
+	for ( /* */ ; pos < size_a; ++pos, ++da, ++dc)
+	{
+		w = ((mp_word) MP_DIGIT_MAX + 1 +		/* MP_RADIX */
+			 (mp_word) *da) - w;
+
+		*dc = LOWER_HALF(w);
+		w = (UPPER_HALF(w) == 0);
+	}
+
+	/* If there is a borrow out at the end, it violates the precondition */
+	assert(w == 0);
+}
+
+/* }}} */
+
+/* {{{ s_kmul(da, db, dc, size_a, size_b) */
+
+static int
+s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b)
+{
+	mp_size		bot_size;
+
+	/* Make sure b is the smaller of the two input values */
+	if (size_b > size_a)
+	{
+		SWAP(mp_digit *, da, db);
+		SWAP(mp_size, size_a, size_b);
+	}
+
+	/*
+	 * Insure that the bottom is the larger half in an odd-length split; the
+	 * code below relies on this being true.
+	 */
+	bot_size = (size_a + 1) / 2;
+
+	/*
+	 * If the values are big enough to bother with recursion, use the
+	 * Karatsuba algorithm to compute the product; otherwise use the normal
+	 * multiplication algorithm
+	 */
+	if (multiply_threshold &&
+		size_a >= multiply_threshold &&
+		size_b > bot_size)
+	{
+
+		mp_digit   *t1,
+				   *t2,
+				   *t3,
+					carry;
+
+		mp_digit   *a_top = da + bot_size;
+		mp_digit   *b_top = db + bot_size;
+
+		mp_size		at_size = size_a - bot_size;
+		mp_size		bt_size = size_b - bot_size;
+		mp_size		buf_size = 2 * bot_size;
+
+		/*
+		 * Do a single allocation for all three temporary buffers needed; each
+		 * buffer must be big enough to hold the product of two bottom halves,
+		 * and one buffer needs space for the completed product; twice the
+		 * space is plenty.
+		 */
+		if ((t1 = s_alloc(4 * buf_size)) == NULL)
+			return 0;
+		t2 = t1 + buf_size;
+		t3 = t2 + buf_size;
+		ZERO(t1, 4 * buf_size);
+
+		/*
+		 * t1 and t2 are initially used as temporaries to compute the inner
+		 * product (a1 + a0)(b1 + b0) = a1b1 + a1b0 + a0b1 + a0b0
+		 */
+		carry = s_uadd(da, a_top, t1, bot_size, at_size);		/* t1 = a1 + a0 */
+		t1[bot_size] = carry;
+
+		carry = s_uadd(db, b_top, t2, bot_size, bt_size);		/* t2 = b1 + b0 */
+		t2[bot_size] = carry;
+
+		(void) s_kmul(t1, t2, t3, bot_size + 1, bot_size + 1);	/* t3 = t1 * t2 */
+
+		/*
+		 * Now we'll get t1 = a0b0 and t2 = a1b1, and subtract them out so
+		 * that we're left with only the pieces we want:  t3 = a1b0 + a0b1
+		 */
+		ZERO(t1, bot_size + 1);
+		ZERO(t2, bot_size + 1);
+		(void) s_kmul(da, db, t1, bot_size, bot_size);	/* t1 = a0 * b0 */
+		(void) s_kmul(a_top, b_top, t2, at_size, bt_size);		/* t2 = a1 * b1 */
+
+		/* Subtract out t1 and t2 to get the inner product */
+		s_usub(t3, t1, t3, buf_size + 2, buf_size);
+		s_usub(t3, t2, t3, buf_size + 2, buf_size);
+
+		/* Assemble the output value */
+		COPY(t1, dc, buf_size);
+		(void) s_uadd(t3, dc + bot_size, dc + bot_size,
+					  buf_size + 1, buf_size + 1);
+
+		(void) s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size,
+					  buf_size, buf_size);
+
+		s_free(t1);				/* note t2 and t3 are just internal pointers
+								 * to t1 */
+	}
+	else
+	{
+		s_umul(da, db, dc, size_a, size_b);
+	}
+
+	return 1;
+}
+
+/* }}} */
+
+/* {{{ s_umul(da, db, dc, size_a, size_b) */
+
+static void
+s_umul(mp_digit *da, mp_digit *db, mp_digit *dc,
+	   mp_size size_a, mp_size size_b)
+{
+	mp_size		a,
+				b;
+	mp_word		w;
+
+	for (a = 0; a < size_a; ++a, ++dc, ++da)
+	{
+		mp_digit   *dct = dc;
+		mp_digit   *dbt = db;
+
+		if (*da == 0)
+			continue;
+
+		w = 0;
+		for (b = 0; b < size_b; ++b, ++dbt, ++dct)
+		{
+			w = (mp_word) *da * (mp_word) *dbt + w + (mp_word) *dct;
+
+			*dct = LOWER_HALF(w);
+			w = UPPER_HALF(w);
+		}
+
+		*dct = (mp_digit) w;
+	}
+}
+
+/* }}} */
+
+/* {{{ s_ksqr(da, dc, size_a) */
+
+static int
+s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a)
+{
+	if (multiply_threshold && size_a > multiply_threshold)
+	{
+		mp_size		bot_size = (size_a + 1) / 2;
+		mp_digit   *a_top = da + bot_size;
+		mp_digit   *t1,
+				   *t2,
+				   *t3;
+		mp_size		at_size = size_a - bot_size;
+		mp_size		buf_size = 2 * bot_size;
+
+		if ((t1 = s_alloc(4 * buf_size)) == NULL)
+			return 0;
+		t2 = t1 + buf_size;
+		t3 = t2 + buf_size;
+		ZERO(t1, 4 * buf_size);
+
+		(void) s_ksqr(da, t1, bot_size);		/* t1 = a0 ^ 2 */
+		(void) s_ksqr(a_top, t2, at_size);		/* t2 = a1 ^ 2 */
+
+		(void) s_kmul(da, a_top, t3, bot_size, at_size);		/* t3 = a0 * a1 */
+
+		/* Quick multiply t3 by 2, shifting left (can't overflow) */
+		{
+			int			i,
+						top = bot_size + at_size;
+			mp_word		w,
+						save = 0;
+
+			for (i = 0; i < top; ++i)
+			{
+				w = t3[i];
+				w = (w << 1) | save;
+				t3[i] = LOWER_HALF(w);
+				save = UPPER_HALF(w);
+			}
+			t3[i] = LOWER_HALF(save);
+		}
+
+		/* Assemble the output value */
+		COPY(t1, dc, 2 * bot_size);
+		(void) s_uadd(t3, dc + bot_size, dc + bot_size,
+					  buf_size + 1, buf_size + 1);
+
+		(void) s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size,
+					  buf_size, buf_size);
+
+		px_free(t1);			/* note that t2 and t2 are internal pointers
+								 * only */
+
+	}
+	else
+	{
+		s_usqr(da, dc, size_a);
+	}
+
+	return 1;
+}
+
+/* }}} */
+
+/* {{{ s_usqr(da, dc, size_a) */
+
+static void
+s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a)
+{
+	mp_size		i,
+				j;
+	mp_word		w;
+
+	for (i = 0; i < size_a; ++i, dc += 2, ++da)
+	{
+		mp_digit   *dct = dc,
+				   *dat = da;
+
+		if (*da == 0)
+			continue;
+
+		/* Take care of the first digit, no rollover */
+		w = (mp_word) *dat * (mp_word) *dat + (mp_word) *dct;
+		*dct = LOWER_HALF(w);
+		w = UPPER_HALF(w);
+		++dat;
+		++dct;
+
+		for (j = i + 1; j < size_a; ++j, ++dat, ++dct)
+		{
+			mp_word		t = (mp_word) *da * (mp_word) *dat;
+			mp_word		u = w + (mp_word) *dct,
+						ov = 0;
+
+			/* Check if doubling t will overflow a word */
+			if (HIGH_BIT_SET(t))
+				ov = 1;
+
+			w = t + t;
+
+			/* Check if adding u to w will overflow a word */
+			if (ADD_WILL_OVERFLOW(w, u))
+				ov = 1;
+
+			w += u;
+
+			*dct = LOWER_HALF(w);
+			w = UPPER_HALF(w);
+			if (ov)
+			{
+				w += MP_DIGIT_MAX;		/* MP_RADIX */
+				++w;
+			}
+		}
+
+		w = w + *dct;
+		*dct = (mp_digit) w;
+		while ((w = UPPER_HALF(w)) != 0)
+		{
+			++dct;
+			w = w + *dct;
+			*dct = LOWER_HALF(w);
+		}
+
+		assert(w == 0);
+	}
+}
+
+/* }}} */
+
+/* {{{ s_dadd(a, b) */
+
+static void
+s_dadd(mp_int a, mp_digit b)
+{
+	mp_word		w = 0;
+	mp_digit   *da = MP_DIGITS(a);
+	mp_size		ua = MP_USED(a);
+
+	w = (mp_word) *da + b;
+	*da++ = LOWER_HALF(w);
+	w = UPPER_HALF(w);
+
+	for (ua -= 1; ua > 0; --ua, ++da)
+	{
+		w = (mp_word) *da + w;
+
+		*da = LOWER_HALF(w);
+		w = UPPER_HALF(w);
+	}
+
+	if (w)
+	{
+		*da = (mp_digit) w;
+		MP_USED(a) += 1;
+	}
+}
+
+/* }}} */
+
+/* {{{ s_dmul(a, b) */
+
+static void
+s_dmul(mp_int a, mp_digit b)
+{
+	mp_word		w = 0;
+	mp_digit   *da = MP_DIGITS(a);
+	mp_size		ua = MP_USED(a);
+
+	while (ua > 0)
+	{
+		w = (mp_word) *da * b + w;
+		*da++ = LOWER_HALF(w);
+		w = UPPER_HALF(w);
+		--ua;
+	}
+
+	if (w)
+	{
+		*da = (mp_digit) w;
+		MP_USED(a) += 1;
+	}
+}
+
+/* }}} */
+
+/* {{{ s_dbmul(da, b, dc, size_a) */
+
+static void
+s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a)
+{
+	mp_word		w = 0;
+
+	while (size_a > 0)
+	{
+		w = (mp_word) *da++ * (mp_word) b + w;
+
+		*dc++ = LOWER_HALF(w);
+		w = UPPER_HALF(w);
+		--size_a;
+	}
+
+	if (w)
+		*dc = LOWER_HALF(w);
+}
+
+/* }}} */
+
+/* {{{ s_ddiv(da, d, dc, size_a) */
+
+static mp_digit
+s_ddiv(mp_int a, mp_digit b)
+{
+	mp_word		w = 0,
+				qdigit;
+	mp_size		ua = MP_USED(a);
+	mp_digit   *da = MP_DIGITS(a) + ua - 1;
+
+	for ( /* */ ; ua > 0; --ua, --da)
+	{
+		w = (w << MP_DIGIT_BIT) | *da;
+
+		if (w >= b)
+		{
+			qdigit = w / b;
+			w = w % b;
+		}
+		else
+		{
+			qdigit = 0;
+		}
+
+		*da = (mp_digit) qdigit;
+	}
+
+	CLAMP(a);
+	return (mp_digit) w;
+}
+
+/* }}} */
+
+/* {{{ s_qdiv(z, p2) */
+
+static void
+s_qdiv(mp_int z, mp_size p2)
+{
+	mp_size		ndig = p2 / MP_DIGIT_BIT,
+				nbits = p2 % MP_DIGIT_BIT;
+	mp_size		uz = MP_USED(z);
+
+	if (ndig)
+	{
+		mp_size		mark;
+		mp_digit   *to,
+				   *from;
+
+		if (ndig >= uz)
+		{
+			mp_int_zero(z);
+			return;
+		}
+
+		to = MP_DIGITS(z);
+		from = to + ndig;
+
+		for (mark = ndig; mark < uz; ++mark)
+			*to++ = *from++;
+
+		MP_USED(z) = uz - ndig;
+	}
+
+	if (nbits)
+	{
+		mp_digit	d = 0,
+				   *dz,
+					save;
+		mp_size		up = MP_DIGIT_BIT - nbits;
+
+		uz = MP_USED(z);
+		dz = MP_DIGITS(z) + uz - 1;
+
+		for ( /* */ ; uz > 0; --uz, --dz)
+		{
+			save = *dz;
+
+			*dz = (*dz >> nbits) | (d << up);
+			d = save;
+		}
+
+		CLAMP(z);
+	}
+
+	if (MP_USED(z) == 1 && z->digits[0] == 0)
+		MP_SIGN(z) = MP_ZPOS;
+}
+
+/* }}} */
+
+/* {{{ s_qmod(z, p2) */
+
+static void
+s_qmod(mp_int z, mp_size p2)
+{
+	mp_size		start = p2 / MP_DIGIT_BIT + 1,
+				rest = p2 % MP_DIGIT_BIT;
+	mp_size		uz = MP_USED(z);
+	mp_digit	mask = (1 << rest) - 1;
+
+	if (start <= uz)
+	{
+		MP_USED(z) = start;
+		z->digits[start - 1] &= mask;
+		CLAMP(z);
+	}
+}
+
+/* }}} */
+
+/* {{{ s_qmul(z, p2) */
+
+static int
+s_qmul(mp_int z, mp_size p2)
+{
+	mp_size		uz,
+				need,
+				rest,
+				extra,
+				i;
+	mp_digit   *from,
+			   *to,
+				d;
+
+	if (p2 == 0)
+		return 1;
+
+	uz = MP_USED(z);
+	need = p2 / MP_DIGIT_BIT;
+	rest = p2 % MP_DIGIT_BIT;
+
+	/*
+	 * Figure out if we need an extra digit at the top end; this occurs if the
+	 * topmost `rest' bits of the high-order digit of z are not zero, meaning
+	 * they will be shifted off the end if not preserved
+	 */
+	extra = 0;
+	if (rest != 0)
+	{
+		mp_digit   *dz = MP_DIGITS(z) + uz - 1;
+
+		if ((*dz >> (MP_DIGIT_BIT - rest)) != 0)
+			extra = 1;
+	}
+
+	if (!s_pad(z, uz + need + extra))
+		return 0;
+
+	/*
+	 * If we need to shift by whole digits, do that in one pass, then to back
+	 * and shift by partial digits.
+	 */
+	if (need > 0)
+	{
+		from = MP_DIGITS(z) + uz - 1;
+		to = from + need;
+
+		for (i = 0; i < uz; ++i)
+			*to-- = *from--;
+
+		ZERO(MP_DIGITS(z), need);
+		uz += need;
+	}
+
+	if (rest)
+	{
+		d = 0;
+		for (i = need, from = MP_DIGITS(z) + need; i < uz; ++i, ++from)
+		{
+			mp_digit	save = *from;
+
+			*from = (*from << rest) | (d >> (MP_DIGIT_BIT - rest));
+			d = save;
+		}
+
+		d >>= (MP_DIGIT_BIT - rest);
+		if (d != 0)
+		{
+			*from = d;
+			uz += extra;
+		}
+	}
+
+	MP_USED(z) = uz;
+	CLAMP(z);
+
+	return 1;
+}
+
+/* }}} */
+
+/* {{{ s_qsub(z, p2) */
+
+/* Subtract |z| from 2^p2, assuming 2^p2 > |z|, and set z to be positive */
+static int
+s_qsub(mp_int z, mp_size p2)
+{
+	mp_digit	hi = (1 << (p2 % MP_DIGIT_BIT)),
+			   *zp;
+	mp_size		tdig = (p2 / MP_DIGIT_BIT),
+				pos;
+	mp_word		w = 0;
+
+	if (!s_pad(z, tdig + 1))
+		return 0;
+
+	for (pos = 0, zp = MP_DIGITS(z); pos < tdig; ++pos, ++zp)
+	{
+		w = ((mp_word) MP_DIGIT_MAX + 1) - w - (mp_word) *zp;
+
+		*zp = LOWER_HALF(w);
+		w = UPPER_HALF(w) ? 0 : 1;
+	}
+
+	w = ((mp_word) MP_DIGIT_MAX + 1 + hi) - w - (mp_word) *zp;
+	*zp = LOWER_HALF(w);
+
+	assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */
+
+	MP_SIGN(z) = MP_ZPOS;
+	CLAMP(z);
+
+	return 1;
+}
+
+/* }}} */
+
+/* {{{ s_dp2k(z) */
+
+static int
+s_dp2k(mp_int z)
+{
+	int			k = 0;
+	mp_digit   *dp = MP_DIGITS(z),
+				d;
+
+	if (MP_USED(z) == 1 && *dp == 0)
+		return 1;
+
+	while (*dp == 0)
+	{
+		k += MP_DIGIT_BIT;
+		++dp;
+	}
+
+	d = *dp;
+	while ((d & 1) == 0)
+	{
+		d >>= 1;
+		++k;
+	}
+
+	return k;
+}
+
+/* }}} */
+
+/* {{{ s_isp2(z) */
+
+static int
+s_isp2(mp_int z)
+{
+	mp_size		uz = MP_USED(z),
+				k = 0;
+	mp_digit   *dz = MP_DIGITS(z),
+				d;
+
+	while (uz > 1)
+	{
+		if (*dz++ != 0)
+			return -1;
+		k += MP_DIGIT_BIT;
+		--uz;
+	}
+
+	d = *dz;
+	while (d > 1)
+	{
+		if (d & 1)
+			return -1;
+		++k;
+		d >>= 1;
+	}
+
+	return (int) k;
+}
+
+/* }}} */
+
+/* {{{ s_2expt(z, k) */
+
+static int
+s_2expt(mp_int z, int k)
+{
+	mp_size		ndig,
+				rest;
+	mp_digit   *dz;
+
+	ndig = (k + MP_DIGIT_BIT) / MP_DIGIT_BIT;
+	rest = k % MP_DIGIT_BIT;
+
+	if (!s_pad(z, ndig))
+		return 0;
+
+	dz = MP_DIGITS(z);
+	ZERO(dz, ndig);
+	*(dz + ndig - 1) = (1 << rest);
+	MP_USED(z) = ndig;
+
+	return 1;
+}
+
+/* }}} */
+
+/* {{{ s_norm(a, b) */
+
+static int
+s_norm(mp_int a, mp_int b)
+{
+	mp_digit	d = b->digits[MP_USED(b) - 1];
+	int			k = 0;
+
+	while (d < (mp_digit) ((mp_digit) 1 << (MP_DIGIT_BIT - 1)))
+	{							/* d < (MP_RADIX / 2) */
+		d <<= 1;
+		++k;
+	}
+
+	/* These multiplications can't fail */
+	if (k != 0)
+	{
+		(void) s_qmul(a, (mp_size) k);
+		(void) s_qmul(b, (mp_size) k);
+	}
+
+	return k;
+}
+
+/* }}} */
+
+/* {{{ s_brmu(z, m) */
+
+static mp_result
+s_brmu(mp_int z, mp_int m)
+{
+	mp_size		um = MP_USED(m) * 2;
+
+	if (!s_pad(z, um))
+		return MP_MEMORY;
+
+	s_2expt(z, MP_DIGIT_BIT * um);
+	return mp_int_div(z, m, z, NULL);
+}
+
+/* }}} */
+
+/* {{{ s_reduce(x, m, mu, q1, q2) */
+
+static int
+s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2)
+{
+	mp_size		um = MP_USED(m),
+				umb_p1,
+				umb_m1;
+
+	umb_p1 = (um + 1) * MP_DIGIT_BIT;
+	umb_m1 = (um - 1) * MP_DIGIT_BIT;
+
+	if (mp_int_copy(x, q1) != MP_OK)
+		return 0;
+
+	/* Compute q2 = floor((floor(x / b^(k-1)) * mu) / b^(k+1)) */
+	s_qdiv(q1, umb_m1);
+	UMUL(q1, mu, q2);
+	s_qdiv(q2, umb_p1);
+
+	/* Set x = x mod b^(k+1) */
+	s_qmod(x, umb_p1);
+
+	/*
+	 * Now, q is a guess for the quotient a / m. Compute x - q * m mod
+	 * b^(k+1), replacing x.  This may be off by a factor of 2m, but no more
+	 * than that.
+	 */
+	UMUL(q2, m, q1);
+	s_qmod(q1, umb_p1);
+	(void) mp_int_sub(x, q1, x);	/* can't fail */
+
+	/*
+	 * The result may be < 0; if it is, add b^(k+1) to pin it in the proper
+	 * range.
+	 */
+	if ((CMPZ(x) < 0) && !s_qsub(x, umb_p1))
+		return 0;
+
+	/*
+	 * If x > m, we need to back it off until it is in range. This will be
+	 * required at most twice.
+	 */
+	if (mp_int_compare(x, m) >= 0)
+		(void) mp_int_sub(x, m, x);
+	if (mp_int_compare(x, m) >= 0)
+		(void) mp_int_sub(x, m, x);
+
+	/* At this point, x has been properly reduced. */
+	return 1;
+}
+
+/* }}} */
+
+/* {{{ s_embar(a, b, m, mu, c) */
+
+/* Perform modular exponentiation using Barrett's method, where mu is
+   the reduction constant for m.  Assumes a < m, b > 0. */
+static mp_result
+s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c)
+{
+	mp_digit   *db,
+			   *dbt,
+				umu,
+				d;
+	mpz_t		temp[3];
+	mp_result	res;
+	int			last = 0;
+
+	umu = MP_USED(mu);
+	db = MP_DIGITS(b);
+	dbt = db + MP_USED(b) - 1;
+
+	while (last < 3)
+		SETUP(mp_int_init_size(TEMP(last), 2 * umu), last);
+
+	(void) mp_int_set_value(c, 1);
+
+	/* Take care of low-order digits */
+	while (db < dbt)
+	{
+		int			i;
+
+		for (d = *db, i = MP_DIGIT_BIT; i > 0; --i, d >>= 1)
+		{
+			if (d & 1)
+			{
+				/* The use of a second temporary avoids allocation */
+				UMUL(c, a, TEMP(0));
+				if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2)))
+				{
+					res = MP_MEMORY;
+					goto CLEANUP;
+				}
+				mp_int_copy(TEMP(0), c);
+			}
+
+
+			USQR(a, TEMP(0));
+			assert(MP_SIGN(TEMP(0)) == MP_ZPOS);
+			if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2)))
+			{
+				res = MP_MEMORY;
+				goto CLEANUP;
+			}
+			assert(MP_SIGN(TEMP(0)) == MP_ZPOS);
+			mp_int_copy(TEMP(0), a);
+
+
+		}
+
+		++db;
+	}
+
+	/* Take care of highest-order digit */
+	d = *dbt;
+	for (;;)
+	{
+		if (d & 1)
+		{
+			UMUL(c, a, TEMP(0));
+			if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2)))
+			{
+				res = MP_MEMORY;
+				goto CLEANUP;
+			}
+			mp_int_copy(TEMP(0), c);
+		}
+
+		d >>= 1;
+		if (!d)
+			break;
+
+		USQR(a, TEMP(0));
+		if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2)))
+		{
+			res = MP_MEMORY;
+			goto CLEANUP;
+		}
+		(void) mp_int_copy(TEMP(0), a);
+	}
+
+CLEANUP:
+	while (--last >= 0)
+		mp_int_clear(TEMP(last));
+
+	return res;
+}
+
+/* }}} */
+
+/* {{{ s_udiv(a, b) */
+
+/* Precondition:  a >= b and b > 0
+   Postcondition: a' = a / b, b' = a % b
+ */
+static mp_result
+s_udiv(mp_int a, mp_int b)
+{
+	mpz_t		q,
+				r,
+				t;
+	mp_size		ua,
+				ub,
+				qpos = 0;
+	mp_digit   *da,
+				btop;
+	mp_result	res = MP_OK;
+	int			k,
+				skip = 0;
+
+	/* Force signs to positive */
+	MP_SIGN(a) = MP_ZPOS;
+	MP_SIGN(b) = MP_ZPOS;
+
+	/* Normalize, per Knuth */
+	k = s_norm(a, b);
+
+	ua = MP_USED(a);
+	ub = MP_USED(b);
+	btop = b->digits[ub - 1];
+	if ((res = mp_int_init_size(&q, ua)) != MP_OK)
+		return res;
+	if ((res = mp_int_init_size(&t, ua + 1)) != MP_OK)
+		goto CLEANUP;
+
+	da = MP_DIGITS(a);
+	r.digits = da + ua - 1;		/* The contents of r are shared with a */
+	r.used = 1;
+	r.sign = MP_ZPOS;
+	r.alloc = MP_ALLOC(a);
+	ZERO(t.digits, t.alloc);
+
+	/* Solve for quotient digits, store in q.digits in reverse order */
+	while (r.digits >= da)
+	{
+		assert(qpos <= q.alloc);
+
+		if (s_ucmp(b, &r) > 0)
+		{
+			r.digits -= 1;
+			r.used += 1;
+
+			if (++skip > 1)
+				q.digits[qpos++] = 0;
+
+			CLAMP(&r);
+		}
+		else
+		{
+			mp_word		pfx = r.digits[r.used - 1];
+			mp_word		qdigit;
+
+			if (r.used > 1 && (pfx < btop || r.digits[r.used - 2] == 0))
+			{
+				pfx <<= MP_DIGIT_BIT / 2;
+				pfx <<= MP_DIGIT_BIT / 2;
+				pfx |= r.digits[r.used - 2];
+			}
+
+			qdigit = pfx / btop;
+			if (qdigit > MP_DIGIT_MAX)
+				qdigit = 1;
+
+			s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub);
+			t.used = ub + 1;
+			CLAMP(&t);
+			while (s_ucmp(&t, &r) > 0)
+			{
+				--qdigit;
+				(void) mp_int_sub(&t, b, &t);	/* cannot fail */
+			}
+
+			s_usub(r.digits, t.digits, r.digits, r.used, t.used);
+			CLAMP(&r);
+
+			q.digits[qpos++] = (mp_digit) qdigit;
+			ZERO(t.digits, t.used);
+			skip = 0;
+		}
+	}
+
+	/* Put quotient digits in the correct order, and discard extra zeroes */
+	q.used = qpos;
+	REV(mp_digit, q.digits, qpos);
+	CLAMP(&q);
+
+	/* Denormalize the remainder */
+	CLAMP(a);
+	if (k != 0)
+		s_qdiv(a, k);
+
+	mp_int_copy(a, b);			/* ok:	0 <= r < b */
+	mp_int_copy(&q, a);			/* ok:	q <= a	   */
+
+	mp_int_clear(&t);
+CLEANUP:
+	mp_int_clear(&q);
+	return res;
+}
+
+/* }}} */
+
+/* {{{ s_outlen(z, r) */
+
+/* Precondition:  2 <= r < 64 */
+static int
+s_outlen(mp_int z, mp_size r)
+{
+	mp_result	bits;
+	double		raw;
+
+	bits = mp_int_count_bits(z);
+	raw = (double) bits *s_log2[r];
+
+	return (int) (raw + 0.999999);
+}
+
+/* }}} */
+
+/* {{{ s_inlen(len, r) */
+
+static mp_size
+s_inlen(int len, mp_size r)
+{
+	double		raw = (double) len / s_log2[r];
+	mp_size		bits = (mp_size) (raw + 0.5);
+
+	return (mp_size) ((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT);
+}
+
+/* }}} */
+
+/* {{{ s_ch2val(c, r) */
+
+static int
+s_ch2val(char c, int r)
+{
+	int			out;
+
+	if (isdigit((unsigned char) c))
+		out = c - '0';
+	else if (r > 10 && isalpha((unsigned char) c))
+		out = toupper((unsigned char) c) - 'A' + 10;
+	else
+		return -1;
+
+	return (out >= r) ? -1 : out;
+}
+
+/* }}} */
+
+/* {{{ s_val2ch(v, caps) */
+
+static char
+s_val2ch(int v, int caps)
+{
+	assert(v >= 0);
+
+	if (v < 10)
+		return v + '0';
+	else
+	{
+		char		out = (v - 10) + 'a';
+
+		if (caps)
+			return toupper((unsigned char) out);
+		else
+			return out;
+	}
+}
+
+/* }}} */
+
+/* {{{ s_2comp(buf, len) */
+
+static void
+s_2comp(unsigned char *buf, int len)
+{
+	int			i;
+	unsigned short s = 1;
+
+	for (i = len - 1; i >= 0; --i)
+	{
+		unsigned char c = ~buf[i];
+
+		s = c + s;
+		c = s & UCHAR_MAX;
+		s >>= CHAR_BIT;
+
+		buf[i] = c;
+	}
+
+	/* last carry out is ignored */
+}
+
+/* }}} */
+
+/* {{{ s_tobin(z, buf, *limpos) */
+
+static mp_result
+s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad)
+{
+	mp_size		uz;
+	mp_digit   *dz;
+	int			pos = 0,
+				limit = *limpos;
+
+	uz = MP_USED(z);
+	dz = MP_DIGITS(z);
+	while (uz > 0 && pos < limit)
+	{
+		mp_digit	d = *dz++;
+		int			i;
+
+		for (i = sizeof(mp_digit); i > 0 && pos < limit; --i)
+		{
+			buf[pos++] = (unsigned char) d;
+			d >>= CHAR_BIT;
+
+			/* Don't write leading zeroes */
+			if (d == 0 && uz == 1)
+				i = 0;			/* exit loop without signaling truncation */
+		}
+
+		/* Detect truncation (loop exited with pos >= limit) */
+		if (i > 0)
+			break;
+
+		--uz;
+	}
+
+	if (pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1)))
+	{
+		if (pos < limit)
+			buf[pos++] = 0;
+		else
+			uz = 1;
+	}
+
+	/* Digits are in reverse order, fix that */
+	REV(unsigned char, buf, pos);
+
+	/* Return the number of bytes actually written */
+	*limpos = pos;
+
+	return (uz == 0) ? MP_OK : MP_TRUNC;
+}
+
+/* }}} */
+
+/* {{{ s_print(tag, z) */
+
+#if 0
+void
+s_print(char *tag, mp_int z)
+{
+	int			i;
+
+	fprintf(stderr, "%s: %c ", tag,
+			(MP_SIGN(z) == MP_NEG) ? '-' : '+');
+
+	for (i = MP_USED(z) - 1; i >= 0; --i)
+		fprintf(stderr, "%0*X", (int) (MP_DIGIT_BIT / 4), z->digits[i]);
+
+	fputc('\n', stderr);
+
+}
+
+void
+s_print_buf(char *tag, mp_digit *buf, mp_size num)
+{
+	int			i;
+
+	fprintf(stderr, "%s: ", tag);
+
+	for (i = num - 1; i >= 0; --i)
+		fprintf(stderr, "%0*X", (int) (MP_DIGIT_BIT / 4), buf[i]);
+
+	fputc('\n', stderr);
+}
+#endif
+
+/* }}} */
+
+/* HERE THERE BE DRAGONS */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/imath.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/imath.h b/contrib/pgcrypto/imath.h
new file mode 100644
index 0000000..f2b02d0
--- /dev/null
+++ b/contrib/pgcrypto/imath.h
@@ -0,0 +1,217 @@
+/*
+  Name:		imath.h
+  Purpose:	Arbitrary precision integer arithmetic routines.
+  Author:	M. J. Fromberger <http://spinning-yarns.org/michael/sw/>
+  Info:		Id: imath.h 21 2006-04-02 18:58:36Z sting
+
+  Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved.
+
+  Permission is hereby granted, free of charge, to any person
+  obtaining a copy of this software and associated documentation files
+  (the "Software"), to deal in the Software without restriction,
+  including without limitation the rights to use, copy, modify, merge,
+  publish, distribute, sublicense, and/or sell copies of the Software,
+  and to permit persons to whom the Software is furnished to do so,
+  subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be
+  included in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT.	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+ */
+/* contrib/pgcrypto/imath.h */
+
+#ifndef IMATH_H_
+#define IMATH_H_
+
+/* use always 32bit digits - should some arch use 16bit digits? */
+#define USE_LONG_LONG
+
+#include <limits.h>
+
+typedef unsigned char mp_sign;
+typedef unsigned int mp_size;
+typedef int mp_result;
+
+#ifdef USE_LONG_LONG
+typedef uint32 mp_digit;
+typedef uint64 mp_word;
+
+#define MP_DIGIT_MAX	   0xFFFFFFFFULL
+#define MP_WORD_MAX		   0xFFFFFFFFFFFFFFFFULL
+#else
+typedef uint16 mp_digit;
+typedef uint32 mp_word;
+
+#define MP_DIGIT_MAX	   0xFFFFUL
+#define MP_WORD_MAX		   0xFFFFFFFFUL
+#endif
+
+typedef struct mpz
+{
+	mp_digit   *digits;
+	mp_size		alloc;
+	mp_size		used;
+	mp_sign		sign;
+} mpz_t    ,
+		   *mp_int;
+
+#define MP_DIGITS(Z) ((Z)->digits)
+#define MP_ALLOC(Z)  ((Z)->alloc)
+#define MP_USED(Z)	 ((Z)->used)
+#define MP_SIGN(Z)	 ((Z)->sign)
+
+extern const mp_result MP_OK;
+extern const mp_result MP_FALSE;
+extern const mp_result MP_TRUE;
+extern const mp_result MP_MEMORY;
+extern const mp_result MP_RANGE;
+extern const mp_result MP_UNDEF;
+extern const mp_result MP_TRUNC;
+extern const mp_result MP_BADARG;
+
+#define MP_DIGIT_BIT	(sizeof(mp_digit) * CHAR_BIT)
+#define MP_WORD_BIT		(sizeof(mp_word) * CHAR_BIT)
+
+#define MP_MIN_RADIX	2
+#define MP_MAX_RADIX	36
+
+extern const mp_sign MP_NEG;
+extern const mp_sign MP_ZPOS;
+
+#define mp_int_is_odd(Z)  ((Z)->digits[0] & 1)
+#define mp_int_is_even(Z) !((Z)->digits[0] & 1)
+
+mp_size		mp_get_default_precision(void);
+void		mp_set_default_precision(mp_size s);
+mp_size		mp_get_multiply_threshold(void);
+void		mp_set_multiply_threshold(mp_size s);
+
+mp_result	mp_int_init(mp_int z);
+mp_int		mp_int_alloc(void);
+mp_result	mp_int_init_size(mp_int z, mp_size prec);
+mp_result	mp_int_init_copy(mp_int z, mp_int old);
+mp_result	mp_int_init_value(mp_int z, int value);
+mp_result	mp_int_set_value(mp_int z, int value);
+void		mp_int_clear(mp_int z);
+void		mp_int_free(mp_int z);
+
+mp_result	mp_int_copy(mp_int a, mp_int c);	/* c = a	 */
+void		mp_int_swap(mp_int a, mp_int c);	/* swap a, c */
+void		mp_int_zero(mp_int z);		/* z = 0	 */
+mp_result	mp_int_abs(mp_int a, mp_int c);		/* c = |a|	 */
+mp_result	mp_int_neg(mp_int a, mp_int c);		/* c = -a	 */
+mp_result	mp_int_add(mp_int a, mp_int b, mp_int c);	/* c = a + b */
+mp_result	mp_int_add_value(mp_int a, int value, mp_int c);
+mp_result	mp_int_sub(mp_int a, mp_int b, mp_int c);	/* c = a - b */
+mp_result	mp_int_sub_value(mp_int a, int value, mp_int c);
+mp_result	mp_int_mul(mp_int a, mp_int b, mp_int c);	/* c = a * b */
+mp_result	mp_int_mul_value(mp_int a, int value, mp_int c);
+mp_result	mp_int_mul_pow2(mp_int a, int p2, mp_int c);
+mp_result	mp_int_sqr(mp_int a, mp_int c);		/* c = a * a */
+
+mp_result
+mp_int_div(mp_int a, mp_int b,	/* q = a / b */
+		   mp_int q, mp_int r); /* r = a % b */
+mp_result
+mp_int_div_value(mp_int a, int value,	/* q = a / value */
+				 mp_int q, int *r);		/* r = a % value */
+mp_result
+mp_int_div_pow2(mp_int a, int p2,		/* q = a / 2^p2  */
+				mp_int q, mp_int r);	/* r = q % 2^p2  */
+mp_result	mp_int_mod(mp_int a, mp_int m, mp_int c);	/* c = a % m */
+
+#define   mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R))
+mp_result	mp_int_expt(mp_int a, int b, mp_int c);		/* c = a^b	 */
+mp_result	mp_int_expt_value(int a, int b, mp_int c);	/* c = a^b	 */
+
+int			mp_int_compare(mp_int a, mp_int b); /* a <=> b	   */
+int			mp_int_compare_unsigned(mp_int a, mp_int b);		/* |a| <=> |b| */
+int			mp_int_compare_zero(mp_int z);		/* a <=> 0	   */
+int			mp_int_compare_value(mp_int z, int value);	/* a <=> v	   */
+
+/* Returns true if v|a, false otherwise (including errors) */
+int			mp_int_divisible_value(mp_int a, int v);
+
+/* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */
+int			mp_int_is_pow2(mp_int z);
+
+mp_result
+mp_int_exptmod(mp_int a, mp_int b, mp_int m,
+			   mp_int c);		/* c = a^b (mod m) */
+mp_result
+mp_int_exptmod_evalue(mp_int a, int value,
+					  mp_int m, mp_int c);		/* c = a^v (mod m) */
+mp_result
+mp_int_exptmod_bvalue(int value, mp_int b,
+					  mp_int m, mp_int c);		/* c = v^b (mod m) */
+mp_result
+mp_int_exptmod_known(mp_int a, mp_int b,
+					 mp_int m, mp_int mu,
+					 mp_int c); /* c = a^b (mod m) */
+mp_result	mp_int_redux_const(mp_int m, mp_int c);
+
+mp_result	mp_int_invmod(mp_int a, mp_int m, mp_int c);		/* c = 1/a (mod m) */
+
+mp_result	mp_int_gcd(mp_int a, mp_int b, mp_int c);	/* c = gcd(a, b)   */
+
+mp_result
+mp_int_egcd(mp_int a, mp_int b, mp_int c,		/* c = gcd(a, b)   */
+			mp_int x, mp_int y);	/* c = ax + by	   */
+
+mp_result	mp_int_sqrt(mp_int a, mp_int c);	/* c = floor(sqrt(q)) */
+
+/* Convert to an int, if representable (returns MP_RANGE if not). */
+mp_result	mp_int_to_int(mp_int z, int *out);
+
+/* Convert to nul-terminated string with the specified radix, writing at
+   most limit characters including the nul terminator  */
+mp_result mp_int_to_string(mp_int z, mp_size radix,
+				 char *str, int limit);
+
+/* Return the number of characters required to represent
+   z in the given radix.  May over-estimate. */
+mp_result	mp_int_string_len(mp_int z, mp_size radix);
+
+/* Read zero-terminated string into z */
+mp_result	mp_int_read_string(mp_int z, mp_size radix, const char *str);
+mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
+					char **end);
+
+/* Return the number of significant bits in z */
+mp_result	mp_int_count_bits(mp_int z);
+
+/* Convert z to two's complement binary, writing at most limit bytes */
+mp_result	mp_int_to_binary(mp_int z, unsigned char *buf, int limit);
+
+/* Read a two's complement binary value into z from the given buffer */
+mp_result	mp_int_read_binary(mp_int z, unsigned char *buf, int len);
+
+/* Return the number of bytes required to represent z in binary. */
+mp_result	mp_int_binary_len(mp_int z);
+
+/* Convert z to unsigned binary, writing at most limit bytes */
+mp_result	mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit);
+
+/* Read an unsigned binary value into z from the given buffer */
+mp_result	mp_int_read_unsigned(mp_int z, unsigned char *buf, int len);
+
+/* Return the number of bytes required to represent z as unsigned output */
+mp_result	mp_int_unsigned_len(mp_int z);
+
+/* Return a statically allocated string describing error code res */
+const char *mp_error_string(mp_result res);
+
+#if 0
+void		s_print(char *tag, mp_int z);
+void		s_print_buf(char *tag, mp_digit *buf, mp_size num);
+#endif
+
+#endif   /* end IMATH_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/internal-sha2.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/internal-sha2.c b/contrib/pgcrypto/internal-sha2.c
new file mode 100644
index 0000000..f86b478
--- /dev/null
+++ b/contrib/pgcrypto/internal-sha2.c
@@ -0,0 +1,316 @@
+/*
+ * internal.c
+ *		Wrapper for builtin functions
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/internal-sha2.c
+ */
+
+#include "postgres.h"
+
+#include <time.h>
+
+#include "px.h"
+#include "sha2.h"
+
+void		init_sha224(PX_MD *h);
+void		init_sha256(PX_MD *h);
+void		init_sha384(PX_MD *h);
+void		init_sha512(PX_MD *h);
+
+/* SHA224 */
+
+static unsigned
+int_sha224_len(PX_MD *h)
+{
+	return SHA224_DIGEST_LENGTH;
+}
+
+static unsigned
+int_sha224_block_len(PX_MD *h)
+{
+	return SHA224_BLOCK_LENGTH;
+}
+
+static void
+int_sha224_update(PX_MD *h, const uint8 *data, unsigned dlen)
+{
+	SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+	SHA224_Update(ctx, data, dlen);
+}
+
+static void
+int_sha224_reset(PX_MD *h)
+{
+	SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+	SHA224_Init(ctx);
+}
+
+static void
+int_sha224_finish(PX_MD *h, uint8 *dst)
+{
+	SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+	SHA224_Final(dst, ctx);
+}
+
+static void
+int_sha224_free(PX_MD *h)
+{
+	SHA224_CTX *ctx = (SHA224_CTX *) h->p.ptr;
+
+	memset(ctx, 0, sizeof(*ctx));
+	px_free(ctx);
+	px_free(h);
+}
+
+/* SHA256 */
+
+static unsigned
+int_sha256_len(PX_MD *h)
+{
+	return SHA256_DIGEST_LENGTH;
+}
+
+static unsigned
+int_sha256_block_len(PX_MD *h)
+{
+	return SHA256_BLOCK_LENGTH;
+}
+
+static void
+int_sha256_update(PX_MD *h, const uint8 *data, unsigned dlen)
+{
+	SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+	SHA256_Update(ctx, data, dlen);
+}
+
+static void
+int_sha256_reset(PX_MD *h)
+{
+	SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+	SHA256_Init(ctx);
+}
+
+static void
+int_sha256_finish(PX_MD *h, uint8 *dst)
+{
+	SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+	SHA256_Final(dst, ctx);
+}
+
+static void
+int_sha256_free(PX_MD *h)
+{
+	SHA256_CTX *ctx = (SHA256_CTX *) h->p.ptr;
+
+	memset(ctx, 0, sizeof(*ctx));
+	px_free(ctx);
+	px_free(h);
+}
+
+/* SHA384 */
+
+static unsigned
+int_sha384_len(PX_MD *h)
+{
+	return SHA384_DIGEST_LENGTH;
+}
+
+static unsigned
+int_sha384_block_len(PX_MD *h)
+{
+	return SHA384_BLOCK_LENGTH;
+}
+
+static void
+int_sha384_update(PX_MD *h, const uint8 *data, unsigned dlen)
+{
+	SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+	SHA384_Update(ctx, data, dlen);
+}
+
+static void
+int_sha384_reset(PX_MD *h)
+{
+	SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+	SHA384_Init(ctx);
+}
+
+static void
+int_sha384_finish(PX_MD *h, uint8 *dst)
+{
+	SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+	SHA384_Final(dst, ctx);
+}
+
+static void
+int_sha384_free(PX_MD *h)
+{
+	SHA384_CTX *ctx = (SHA384_CTX *) h->p.ptr;
+
+	memset(ctx, 0, sizeof(*ctx));
+	px_free(ctx);
+	px_free(h);
+}
+
+/* SHA512 */
+
+static unsigned
+int_sha512_len(PX_MD *h)
+{
+	return SHA512_DIGEST_LENGTH;
+}
+
+static unsigned
+int_sha512_block_len(PX_MD *h)
+{
+	return SHA512_BLOCK_LENGTH;
+}
+
+static void
+int_sha512_update(PX_MD *h, const uint8 *data, unsigned dlen)
+{
+	SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+	SHA512_Update(ctx, data, dlen);
+}
+
+static void
+int_sha512_reset(PX_MD *h)
+{
+	SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+	SHA512_Init(ctx);
+}
+
+static void
+int_sha512_finish(PX_MD *h, uint8 *dst)
+{
+	SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+	SHA512_Final(dst, ctx);
+}
+
+static void
+int_sha512_free(PX_MD *h)
+{
+	SHA512_CTX *ctx = (SHA512_CTX *) h->p.ptr;
+
+	memset(ctx, 0, sizeof(*ctx));
+	px_free(ctx);
+	px_free(h);
+}
+
+/* init functions */
+
+void
+init_sha224(PX_MD *md)
+{
+	SHA224_CTX *ctx;
+
+	ctx = px_alloc(sizeof(*ctx));
+	memset(ctx, 0, sizeof(*ctx));
+
+	md->p.ptr = ctx;
+
+	md->result_size = int_sha224_len;
+	md->block_size = int_sha224_block_len;
+	md->reset = int_sha224_reset;
+	md->update = int_sha224_update;
+	md->finish = int_sha224_finish;
+	md->free = int_sha224_free;
+
+	md->reset(md);
+}
+
+void
+init_sha256(PX_MD *md)
+{
+	SHA256_CTX *ctx;
+
+	ctx = px_alloc(sizeof(*ctx));
+	memset(ctx, 0, sizeof(*ctx));
+
+	md->p.ptr = ctx;
+
+	md->result_size = int_sha256_len;
+	md->block_size = int_sha256_block_len;
+	md->reset = int_sha256_reset;
+	md->update = int_sha256_update;
+	md->finish = int_sha256_finish;
+	md->free = int_sha256_free;
+
+	md->reset(md);
+}
+
+void
+init_sha384(PX_MD *md)
+{
+	SHA384_CTX *ctx;
+
+	ctx = px_alloc(sizeof(*ctx));
+	memset(ctx, 0, sizeof(*ctx));
+
+	md->p.ptr = ctx;
+
+	md->result_size = int_sha384_len;
+	md->block_size = int_sha384_block_len;
+	md->reset = int_sha384_reset;
+	md->update = int_sha384_update;
+	md->finish = int_sha384_finish;
+	md->free = int_sha384_free;
+
+	md->reset(md);
+}
+
+void
+init_sha512(PX_MD *md)
+{
+	SHA512_CTX *ctx;
+
+	ctx = px_alloc(sizeof(*ctx));
+	memset(ctx, 0, sizeof(*ctx));
+
+	md->p.ptr = ctx;
+
+	md->result_size = int_sha512_len;
+	md->block_size = int_sha512_block_len;
+	md->reset = int_sha512_reset;
+	md->update = int_sha512_update;
+	md->finish = int_sha512_finish;
+	md->free = int_sha512_free;
+
+	md->reset(md);
+}


[03/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/rijndael.tbl
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/rijndael.tbl b/contrib/pgcrypto/rijndael.tbl
new file mode 100644
index 0000000..c7610c0
--- /dev/null
+++ b/contrib/pgcrypto/rijndael.tbl
@@ -0,0 +1,1138 @@
+/* Generated by rijndael.c */
+
+static const u1byte  pow_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u1byte  log_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u1byte  sbx_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u1byte  isb_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u4byte  ft_tab[4][256] = {
+{
+  0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
+  0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
+  0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
+  0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
+  0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
+  0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
+  0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
+  0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
+  0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
+  0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
+  0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
+  0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
+  0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
+  0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
+  0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
+  0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
+  0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
+  0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
+  0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
+  0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
+  0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
+  0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
+  0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
+  0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
+  0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
+  0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
+  0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
+  0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
+  0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
+  0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
+  0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
+  0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
+  0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
+  0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
+  0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
+  0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
+  0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
+  0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
+  0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
+  0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
+  0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
+  0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
+  0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
+  0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
+  0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
+  0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
+  0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
+  0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
+  0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
+  0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
+  0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
+  0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
+  0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
+  0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
+  0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
+  0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
+  0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
+  0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
+  0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
+  0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
+  0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
+  0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
+  0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
+  0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
+}, {
+  0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d,
+  0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
+  0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
+  0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a,
+  0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87,
+  0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
+  0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea,
+  0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b,
+  0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a,
+  0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
+  0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908,
+  0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
+  0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e,
+  0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5,
+  0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
+  0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f,
+  0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e,
+  0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
+  0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce,
+  0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
+  0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c,
+  0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed,
+  0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b,
+  0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
+  0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16,
+  0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194,
+  0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81,
+  0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3,
+  0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a,
+  0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
+  0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263,
+  0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d,
+  0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
+  0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39,
+  0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47,
+  0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
+  0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f,
+  0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83,
+  0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c,
+  0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
+  0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e,
+  0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
+  0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6,
+  0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b,
+  0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
+  0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0,
+  0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25,
+  0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
+  0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72,
+  0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
+  0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
+  0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85,
+  0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa,
+  0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
+  0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0,
+  0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9,
+  0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233,
+  0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7,
+  0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920,
+  0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
+  0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17,
+  0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8,
+  0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
+  0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a
+}, {
+  0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b,
+  0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
+  0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
+  0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76,
+  0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d,
+  0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
+  0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf,
+  0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0,
+  0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26,
+  0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
+  0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1,
+  0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
+  0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3,
+  0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a,
+  0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
+  0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75,
+  0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a,
+  0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
+  0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3,
+  0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
+  0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced,
+  0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b,
+  0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39,
+  0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
+  0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb,
+  0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485,
+  0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f,
+  0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8,
+  0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f,
+  0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
+  0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321,
+  0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2,
+  0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
+  0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917,
+  0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d,
+  0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
+  0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc,
+  0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388,
+  0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14,
+  0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
+  0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a,
+  0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
+  0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662,
+  0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79,
+  0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
+  0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9,
+  0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea,
+  0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
+  0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e,
+  0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
+  0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
+  0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a,
+  0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66,
+  0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
+  0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9,
+  0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e,
+  0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311,
+  0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794,
+  0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9,
+  0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
+  0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d,
+  0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868,
+  0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
+  0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16
+}, {
+  0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b,
+  0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
+  0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
+  0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676,
+  0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d,
+  0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
+  0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf,
+  0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0,
+  0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626,
+  0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
+  0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1,
+  0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
+  0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3,
+  0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a,
+  0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
+  0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575,
+  0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a,
+  0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
+  0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3,
+  0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
+  0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded,
+  0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b,
+  0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939,
+  0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
+  0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb,
+  0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585,
+  0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f,
+  0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8,
+  0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f,
+  0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
+  0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121,
+  0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2,
+  0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
+  0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717,
+  0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d,
+  0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
+  0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc,
+  0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888,
+  0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414,
+  0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
+  0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a,
+  0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
+  0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262,
+  0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979,
+  0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
+  0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9,
+  0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea,
+  0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
+  0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e,
+  0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
+  0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
+  0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a,
+  0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666,
+  0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
+  0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9,
+  0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e,
+  0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111,
+  0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494,
+  0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9,
+  0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
+  0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d,
+  0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868,
+  0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
+  0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616
+}
+};
+
+static const u4byte  it_tab[4][256] = {
+{
+  0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
+  0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
+  0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,
+  0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
+  0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
+  0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
+  0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295,
+  0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
+  0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927,
+  0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
+  0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362,
+  0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
+  0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52,
+  0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
+  0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
+  0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
+  0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e,
+  0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
+  0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4,
+  0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
+  0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d,
+  0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
+  0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967,
+  0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
+  0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
+  0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
+  0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36,
+  0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
+  0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b,
+  0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
+  0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12,
+  0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
+  0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,
+  0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
+  0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
+  0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
+  0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7,
+  0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
+  0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947,
+  0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
+  0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498,
+  0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
+  0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54,
+  0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
+  0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
+  0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
+  0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83,
+  0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
+  0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029,
+  0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
+  0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733,
+  0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
+  0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4,
+  0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
+  0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
+  0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
+  0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb,
+  0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
+  0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773,
+  0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
+  0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2,
+  0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
+  0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,
+  0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0
+}, {
+  0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96,
+  0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93,
+  0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525,
+  0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f,
+  0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1,
+  0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6,
+  0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da,
+  0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44,
+  0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd,
+  0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4,
+  0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245,
+  0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994,
+  0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7,
+  0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a,
+  0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5,
+  0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c,
+  0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1,
+  0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a,
+  0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475,
+  0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51,
+  0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46,
+  0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff,
+  0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777,
+  0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db,
+  0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000,
+  0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e,
+  0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627,
+  0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a,
+  0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e,
+  0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16,
+  0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d,
+  0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8,
+  0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd,
+  0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34,
+  0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863,
+  0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420,
+  0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d,
+  0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0,
+  0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722,
+  0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef,
+  0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836,
+  0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4,
+  0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462,
+  0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5,
+  0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3,
+  0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b,
+  0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8,
+  0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6,
+  0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6,
+  0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0,
+  0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315,
+  0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f,
+  0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df,
+  0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f,
+  0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e,
+  0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13,
+  0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89,
+  0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c,
+  0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf,
+  0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886,
+  0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f,
+  0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41,
+  0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490,
+  0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042
+}, {
+  0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e,
+  0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303,
+  0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c,
+  0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3,
+  0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0,
+  0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9,
+  0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59,
+  0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8,
+  0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71,
+  0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a,
+  0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f,
+  0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b,
+  0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8,
+  0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab,
+  0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508,
+  0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82,
+  0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2,
+  0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe,
+  0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb,
+  0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110,
+  0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd,
+  0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15,
+  0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e,
+  0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee,
+  0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000,
+  0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72,
+  0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739,
+  0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e,
+  0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91,
+  0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a,
+  0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17,
+  0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9,
+  0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60,
+  0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e,
+  0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1,
+  0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011,
+  0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1,
+  0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3,
+  0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264,
+  0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90,
+  0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b,
+  0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf,
+  0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246,
+  0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af,
+  0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312,
+  0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb,
+  0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a,
+  0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8,
+  0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c,
+  0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066,
+  0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8,
+  0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6,
+  0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04,
+  0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51,
+  0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41,
+  0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347,
+  0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c,
+  0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1,
+  0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37,
+  0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
+  0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40,
+  0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195,
+  0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1,
+  0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257
+}, {
+  0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27,
+  0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3,
+  0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02,
+  0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362,
+  0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe,
+  0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
+  0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952,
+  0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9,
+  0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9,
+  0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace,
+  0x63184adf, 0xe582311a, 0x97603351, 0x62457f53,
+  0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
+  0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b,
+  0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55,
+  0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
+  0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216,
+  0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269,
+  0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
+  0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6,
+  0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e,
+  0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6,
+  0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550,
+  0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9,
+  0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
+  0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000,
+  0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a,
+  0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d,
+  0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36,
+  0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b,
+  0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
+  0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b,
+  0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e,
+  0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
+  0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb,
+  0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4,
+  0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
+  0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129,
+  0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1,
+  0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9,
+  0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033,
+  0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4,
+  0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
+  0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e,
+  0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3,
+  0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
+  0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b,
+  0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f,
+  0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
+  0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0,
+  0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2,
+  0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
+  0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691,
+  0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496,
+  0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
+  0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b,
+  0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6,
+  0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13,
+  0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147,
+  0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7,
+  0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
+  0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3,
+  0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d,
+  0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156,
+  0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8
+}
+};
+
+static const u4byte  fl_tab[4][256] = {
+{
+  0x00000063, 0x0000007c, 0x00000077, 0x0000007b,
+  0x000000f2, 0x0000006b, 0x0000006f, 0x000000c5,
+  0x00000030, 0x00000001, 0x00000067, 0x0000002b,
+  0x000000fe, 0x000000d7, 0x000000ab, 0x00000076,
+  0x000000ca, 0x00000082, 0x000000c9, 0x0000007d,
+  0x000000fa, 0x00000059, 0x00000047, 0x000000f0,
+  0x000000ad, 0x000000d4, 0x000000a2, 0x000000af,
+  0x0000009c, 0x000000a4, 0x00000072, 0x000000c0,
+  0x000000b7, 0x000000fd, 0x00000093, 0x00000026,
+  0x00000036, 0x0000003f, 0x000000f7, 0x000000cc,
+  0x00000034, 0x000000a5, 0x000000e5, 0x000000f1,
+  0x00000071, 0x000000d8, 0x00000031, 0x00000015,
+  0x00000004, 0x000000c7, 0x00000023, 0x000000c3,
+  0x00000018, 0x00000096, 0x00000005, 0x0000009a,
+  0x00000007, 0x00000012, 0x00000080, 0x000000e2,
+  0x000000eb, 0x00000027, 0x000000b2, 0x00000075,
+  0x00000009, 0x00000083, 0x0000002c, 0x0000001a,
+  0x0000001b, 0x0000006e, 0x0000005a, 0x000000a0,
+  0x00000052, 0x0000003b, 0x000000d6, 0x000000b3,
+  0x00000029, 0x000000e3, 0x0000002f, 0x00000084,
+  0x00000053, 0x000000d1, 0x00000000, 0x000000ed,
+  0x00000020, 0x000000fc, 0x000000b1, 0x0000005b,
+  0x0000006a, 0x000000cb, 0x000000be, 0x00000039,
+  0x0000004a, 0x0000004c, 0x00000058, 0x000000cf,
+  0x000000d0, 0x000000ef, 0x000000aa, 0x000000fb,
+  0x00000043, 0x0000004d, 0x00000033, 0x00000085,
+  0x00000045, 0x000000f9, 0x00000002, 0x0000007f,
+  0x00000050, 0x0000003c, 0x0000009f, 0x000000a8,
+  0x00000051, 0x000000a3, 0x00000040, 0x0000008f,
+  0x00000092, 0x0000009d, 0x00000038, 0x000000f5,
+  0x000000bc, 0x000000b6, 0x000000da, 0x00000021,
+  0x00000010, 0x000000ff, 0x000000f3, 0x000000d2,
+  0x000000cd, 0x0000000c, 0x00000013, 0x000000ec,
+  0x0000005f, 0x00000097, 0x00000044, 0x00000017,
+  0x000000c4, 0x000000a7, 0x0000007e, 0x0000003d,
+  0x00000064, 0x0000005d, 0x00000019, 0x00000073,
+  0x00000060, 0x00000081, 0x0000004f, 0x000000dc,
+  0x00000022, 0x0000002a, 0x00000090, 0x00000088,
+  0x00000046, 0x000000ee, 0x000000b8, 0x00000014,
+  0x000000de, 0x0000005e, 0x0000000b, 0x000000db,
+  0x000000e0, 0x00000032, 0x0000003a, 0x0000000a,
+  0x00000049, 0x00000006, 0x00000024, 0x0000005c,
+  0x000000c2, 0x000000d3, 0x000000ac, 0x00000062,
+  0x00000091, 0x00000095, 0x000000e4, 0x00000079,
+  0x000000e7, 0x000000c8, 0x00000037, 0x0000006d,
+  0x0000008d, 0x000000d5, 0x0000004e, 0x000000a9,
+  0x0000006c, 0x00000056, 0x000000f4, 0x000000ea,
+  0x00000065, 0x0000007a, 0x000000ae, 0x00000008,
+  0x000000ba, 0x00000078, 0x00000025, 0x0000002e,
+  0x0000001c, 0x000000a6, 0x000000b4, 0x000000c6,
+  0x000000e8, 0x000000dd, 0x00000074, 0x0000001f,
+  0x0000004b, 0x000000bd, 0x0000008b, 0x0000008a,
+  0x00000070, 0x0000003e, 0x000000b5, 0x00000066,
+  0x00000048, 0x00000003, 0x000000f6, 0x0000000e,
+  0x00000061, 0x00000035, 0x00000057, 0x000000b9,
+  0x00000086, 0x000000c1, 0x0000001d, 0x0000009e,
+  0x000000e1, 0x000000f8, 0x00000098, 0x00000011,
+  0x00000069, 0x000000d9, 0x0000008e, 0x00000094,
+  0x0000009b, 0x0000001e, 0x00000087, 0x000000e9,
+  0x000000ce, 0x00000055, 0x00000028, 0x000000df,
+  0x0000008c, 0x000000a1, 0x00000089, 0x0000000d,
+  0x000000bf, 0x000000e6, 0x00000042, 0x00000068,
+  0x00000041, 0x00000099, 0x0000002d, 0x0000000f,
+  0x000000b0, 0x00000054, 0x000000bb, 0x00000016
+}, {
+  0x00006300, 0x00007c00, 0x00007700, 0x00007b00,
+  0x0000f200, 0x00006b00, 0x00006f00, 0x0000c500,
+  0x00003000, 0x00000100, 0x00006700, 0x00002b00,
+  0x0000fe00, 0x0000d700, 0x0000ab00, 0x00007600,
+  0x0000ca00, 0x00008200, 0x0000c900, 0x00007d00,
+  0x0000fa00, 0x00005900, 0x00004700, 0x0000f000,
+  0x0000ad00, 0x0000d400, 0x0000a200, 0x0000af00,
+  0x00009c00, 0x0000a400, 0x00007200, 0x0000c000,
+  0x0000b700, 0x0000fd00, 0x00009300, 0x00002600,
+  0x00003600, 0x00003f00, 0x0000f700, 0x0000cc00,
+  0x00003400, 0x0000a500, 0x0000e500, 0x0000f100,
+  0x00007100, 0x0000d800, 0x00003100, 0x00001500,
+  0x00000400, 0x0000c700, 0x00002300, 0x0000c300,
+  0x00001800, 0x00009600, 0x00000500, 0x00009a00,
+  0x00000700, 0x00001200, 0x00008000, 0x0000e200,
+  0x0000eb00, 0x00002700, 0x0000b200, 0x00007500,
+  0x00000900, 0x00008300, 0x00002c00, 0x00001a00,
+  0x00001b00, 0x00006e00, 0x00005a00, 0x0000a000,
+  0x00005200, 0x00003b00, 0x0000d600, 0x0000b300,
+  0x00002900, 0x0000e300, 0x00002f00, 0x00008400,
+  0x00005300, 0x0000d100, 0x00000000, 0x0000ed00,
+  0x00002000, 0x0000fc00, 0x0000b100, 0x00005b00,
+  0x00006a00, 0x0000cb00, 0x0000be00, 0x00003900,
+  0x00004a00, 0x00004c00, 0x00005800, 0x0000cf00,
+  0x0000d000, 0x0000ef00, 0x0000aa00, 0x0000fb00,
+  0x00004300, 0x00004d00, 0x00003300, 0x00008500,
+  0x00004500, 0x0000f900, 0x00000200, 0x00007f00,
+  0x00005000, 0x00003c00, 0x00009f00, 0x0000a800,
+  0x00005100, 0x0000a300, 0x00004000, 0x00008f00,
+  0x00009200, 0x00009d00, 0x00003800, 0x0000f500,
+  0x0000bc00, 0x0000b600, 0x0000da00, 0x00002100,
+  0x00001000, 0x0000ff00, 0x0000f300, 0x0000d200,
+  0x0000cd00, 0x00000c00, 0x00001300, 0x0000ec00,
+  0x00005f00, 0x00009700, 0x00004400, 0x00001700,
+  0x0000c400, 0x0000a700, 0x00007e00, 0x00003d00,
+  0x00006400, 0x00005d00, 0x00001900, 0x00007300,
+  0x00006000, 0x00008100, 0x00004f00, 0x0000dc00,
+  0x00002200, 0x00002a00, 0x00009000, 0x00008800,
+  0x00004600, 0x0000ee00, 0x0000b800, 0x00001400,
+  0x0000de00, 0x00005e00, 0x00000b00, 0x0000db00,
+  0x0000e000, 0x00003200, 0x00003a00, 0x00000a00,
+  0x00004900, 0x00000600, 0x00002400, 0x00005c00,
+  0x0000c200, 0x0000d300, 0x0000ac00, 0x00006200,
+  0x00009100, 0x00009500, 0x0000e400, 0x00007900,
+  0x0000e700, 0x0000c800, 0x00003700, 0x00006d00,
+  0x00008d00, 0x0000d500, 0x00004e00, 0x0000a900,
+  0x00006c00, 0x00005600, 0x0000f400, 0x0000ea00,
+  0x00006500, 0x00007a00, 0x0000ae00, 0x00000800,
+  0x0000ba00, 0x00007800, 0x00002500, 0x00002e00,
+  0x00001c00, 0x0000a600, 0x0000b400, 0x0000c600,
+  0x0000e800, 0x0000dd00, 0x00007400, 0x00001f00,
+  0x00004b00, 0x0000bd00, 0x00008b00, 0x00008a00,
+  0x00007000, 0x00003e00, 0x0000b500, 0x00006600,
+  0x00004800, 0x00000300, 0x0000f600, 0x00000e00,
+  0x00006100, 0x00003500, 0x00005700, 0x0000b900,
+  0x00008600, 0x0000c100, 0x00001d00, 0x00009e00,
+  0x0000e100, 0x0000f800, 0x00009800, 0x00001100,
+  0x00006900, 0x0000d900, 0x00008e00, 0x00009400,
+  0x00009b00, 0x00001e00, 0x00008700, 0x0000e900,
+  0x0000ce00, 0x00005500, 0x00002800, 0x0000df00,
+  0x00008c00, 0x0000a100, 0x00008900, 0x00000d00,
+  0x0000bf00, 0x0000e600, 0x00004200, 0x00006800,
+  0x00004100, 0x00009900, 0x00002d00, 0x00000f00,
+  0x0000b000, 0x00005400, 0x0000bb00, 0x00001600
+}, {
+  0x00630000, 0x007c0000, 0x00770000, 0x007b0000,
+  0x00f20000, 0x006b0000, 0x006f0000, 0x00c50000,
+  0x00300000, 0x00010000, 0x00670000, 0x002b0000,
+  0x00fe0000, 0x00d70000, 0x00ab0000, 0x00760000,
+  0x00ca0000, 0x00820000, 0x00c90000, 0x007d0000,
+  0x00fa0000, 0x00590000, 0x00470000, 0x00f00000,
+  0x00ad0000, 0x00d40000, 0x00a20000, 0x00af0000,
+  0x009c0000, 0x00a40000, 0x00720000, 0x00c00000,
+  0x00b70000, 0x00fd0000, 0x00930000, 0x00260000,
+  0x00360000, 0x003f0000, 0x00f70000, 0x00cc0000,
+  0x00340000, 0x00a50000, 0x00e50000, 0x00f10000,
+  0x00710000, 0x00d80000, 0x00310000, 0x00150000,
+  0x00040000, 0x00c70000, 0x00230000, 0x00c30000,
+  0x00180000, 0x00960000, 0x00050000, 0x009a0000,
+  0x00070000, 0x00120000, 0x00800000, 0x00e20000,
+  0x00eb0000, 0x00270000, 0x00b20000, 0x00750000,
+  0x00090000, 0x00830000, 0x002c0000, 0x001a0000,
+  0x001b0000, 0x006e0000, 0x005a0000, 0x00a00000,
+  0x00520000, 0x003b0000, 0x00d60000, 0x00b30000,
+  0x00290000, 0x00e30000, 0x002f0000, 0x00840000,
+  0x00530000, 0x00d10000, 0x00000000, 0x00ed0000,
+  0x00200000, 0x00fc0000, 0x00b10000, 0x005b0000,
+  0x006a0000, 0x00cb0000, 0x00be0000, 0x00390000,
+  0x004a0000, 0x004c0000, 0x00580000, 0x00cf0000,
+  0x00d00000, 0x00ef0000, 0x00aa0000, 0x00fb0000,
+  0x00430000, 0x004d0000, 0x00330000, 0x00850000,
+  0x00450000, 0x00f90000, 0x00020000, 0x007f0000,
+  0x00500000, 0x003c0000, 0x009f0000, 0x00a80000,
+  0x00510000, 0x00a30000, 0x00400000, 0x008f0000,
+  0x00920000, 0x009d0000, 0x00380000, 0x00f50000,
+  0x00bc0000, 0x00b60000, 0x00da0000, 0x00210000,
+  0x00100000, 0x00ff0000, 0x00f30000, 0x00d20000,
+  0x00cd0000, 0x000c0000, 0x00130000, 0x00ec0000,
+  0x005f0000, 0x00970000, 0x00440000, 0x00170000,
+  0x00c40000, 0x00a70000, 0x007e0000, 0x003d0000,
+  0x00640000, 0x005d0000, 0x00190000, 0x00730000,
+  0x00600000, 0x00810000, 0x004f0000, 0x00dc0000,
+  0x00220000, 0x002a0000, 0x00900000, 0x00880000,
+  0x00460000, 0x00ee0000, 0x00b80000, 0x00140000,
+  0x00de0000, 0x005e0000, 0x000b0000, 0x00db0000,
+  0x00e00000, 0x00320000, 0x003a0000, 0x000a0000,
+  0x00490000, 0x00060000, 0x00240000, 0x005c0000,
+  0x00c20000, 0x00d30000, 0x00ac0000, 0x00620000,
+  0x00910000, 0x00950000, 0x00e40000, 0x00790000,
+  0x00e70000, 0x00c80000, 0x00370000, 0x006d0000,
+  0x008d0000, 0x00d50000, 0x004e0000, 0x00a90000,
+  0x006c0000, 0x00560000, 0x00f40000, 0x00ea0000,
+  0x00650000, 0x007a0000, 0x00ae0000, 0x00080000,
+  0x00ba0000, 0x00780000, 0x00250000, 0x002e0000,
+  0x001c0000, 0x00a60000, 0x00b40000, 0x00c60000,
+  0x00e80000, 0x00dd0000, 0x00740000, 0x001f0000,
+  0x004b0000, 0x00bd0000, 0x008b0000, 0x008a0000,
+  0x00700000, 0x003e0000, 0x00b50000, 0x00660000,
+  0x00480000, 0x00030000, 0x00f60000, 0x000e0000,
+  0x00610000, 0x00350000, 0x00570000, 0x00b90000,
+  0x00860000, 0x00c10000, 0x001d0000, 0x009e0000,
+  0x00e10000, 0x00f80000, 0x00980000, 0x00110000,
+  0x00690000, 0x00d90000, 0x008e0000, 0x00940000,
+  0x009b0000, 0x001e0000, 0x00870000, 0x00e90000,
+  0x00ce0000, 0x00550000, 0x00280000, 0x00df0000,
+  0x008c0000, 0x00a10000, 0x00890000, 0x000d0000,
+  0x00bf0000, 0x00e60000, 0x00420000, 0x00680000,
+  0x00410000, 0x00990000, 0x002d0000, 0x000f0000,
+  0x00b00000, 0x00540000, 0x00bb0000, 0x00160000
+}, {
+  0x63000000, 0x7c000000, 0x77000000, 0x7b000000,
+  0xf2000000, 0x6b000000, 0x6f000000, 0xc5000000,
+  0x30000000, 0x01000000, 0x67000000, 0x2b000000,
+  0xfe000000, 0xd7000000, 0xab000000, 0x76000000,
+  0xca000000, 0x82000000, 0xc9000000, 0x7d000000,
+  0xfa000000, 0x59000000, 0x47000000, 0xf0000000,
+  0xad000000, 0xd4000000, 0xa2000000, 0xaf000000,
+  0x9c000000, 0xa4000000, 0x72000000, 0xc0000000,
+  0xb7000000, 0xfd000000, 0x93000000, 0x26000000,
+  0x36000000, 0x3f000000, 0xf7000000, 0xcc000000,
+  0x34000000, 0xa5000000, 0xe5000000, 0xf1000000,
+  0x71000000, 0xd8000000, 0x31000000, 0x15000000,
+  0x04000000, 0xc7000000, 0x23000000, 0xc3000000,
+  0x18000000, 0x96000000, 0x05000000, 0x9a000000,
+  0x07000000, 0x12000000, 0x80000000, 0xe2000000,
+  0xeb000000, 0x27000000, 0xb2000000, 0x75000000,
+  0x09000000, 0x83000000, 0x2c000000, 0x1a000000,
+  0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000,
+  0x52000000, 0x3b000000, 0xd6000000, 0xb3000000,
+  0x29000000, 0xe3000000, 0x2f000000, 0x84000000,
+  0x53000000, 0xd1000000, 0x00000000, 0xed000000,
+  0x20000000, 0xfc000000, 0xb1000000, 0x5b000000,
+  0x6a000000, 0xcb000000, 0xbe000000, 0x39000000,
+  0x4a000000, 0x4c000000, 0x58000000, 0xcf000000,
+  0xd0000000, 0xef000000, 0xaa000000, 0xfb000000,
+  0x43000000, 0x4d000000, 0x33000000, 0x85000000,
+  0x45000000, 0xf9000000, 0x02000000, 0x7f000000,
+  0x50000000, 0x3c000000, 0x9f000000, 0xa8000000,
+  0x51000000, 0xa3000000, 0x40000000, 0x8f000000,
+  0x92000000, 0x9d000000, 0x38000000, 0xf5000000,
+  0xbc000000, 0xb6000000, 0xda000000, 0x21000000,
+  0x10000000, 0xff000000, 0xf3000000, 0xd2000000,
+  0xcd000000, 0x0c000000, 0x13000000, 0xec000000,
+  0x5f000000, 0x97000000, 0x44000000, 0x17000000,
+  0xc4000000, 0xa7000000, 0x7e000000, 0x3d000000,
+  0x64000000, 0x5d000000, 0x19000000, 0x73000000,
+  0x60000000, 0x81000000, 0x4f000000, 0xdc000000,
+  0x22000000, 0x2a000000, 0x90000000, 0x88000000,
+  0x46000000, 0xee000000, 0xb8000000, 0x14000000,
+  0xde000000, 0x5e000000, 0x0b000000, 0xdb000000,
+  0xe0000000, 0x32000000, 0x3a000000, 0x0a000000,
+  0x49000000, 0x06000000, 0x24000000, 0x5c000000,
+  0xc2000000, 0xd3000000, 0xac000000, 0x62000000,
+  0x91000000, 0x95000000, 0xe4000000, 0x79000000,
+  0xe7000000, 0xc8000000, 0x37000000, 0x6d000000,
+  0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000,
+  0x6c000000, 0x56000000, 0xf4000000, 0xea000000,
+  0x65000000, 0x7a000000, 0xae000000, 0x08000000,
+  0xba000000, 0x78000000, 0x25000000, 0x2e000000,
+  0x1c000000, 0xa6000000, 0xb4000000, 0xc6000000,
+  0xe8000000, 0xdd000000, 0x74000000, 0x1f000000,
+  0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000,
+  0x70000000, 0x3e000000, 0xb5000000, 0x66000000,
+  0x48000000, 0x03000000, 0xf6000000, 0x0e000000,
+  0x61000000, 0x35000000, 0x57000000, 0xb9000000,
+  0x86000000, 0xc1000000, 0x1d000000, 0x9e000000,
+  0xe1000000, 0xf8000000, 0x98000000, 0x11000000,
+  0x69000000, 0xd9000000, 0x8e000000, 0x94000000,
+  0x9b000000, 0x1e000000, 0x87000000, 0xe9000000,
+  0xce000000, 0x55000000, 0x28000000, 0xdf000000,
+  0x8c000000, 0xa1000000, 0x89000000, 0x0d000000,
+  0xbf000000, 0xe6000000, 0x42000000, 0x68000000,
+  0x41000000, 0x99000000, 0x2d000000, 0x0f000000,
+  0xb0000000, 0x54000000, 0xbb000000, 0x16000000
+}
+};
+
+static const u4byte  il_tab[4][256] = {
+{
+  0x00000052, 0x00000009, 0x0000006a, 0x000000d5,
+  0x00000030, 0x00000036, 0x000000a5, 0x00000038,
+  0x000000bf, 0x00000040, 0x000000a3, 0x0000009e,
+  0x00000081, 0x000000f3, 0x000000d7, 0x000000fb,
+  0x0000007c, 0x000000e3, 0x00000039, 0x00000082,
+  0x0000009b, 0x0000002f, 0x000000ff, 0x00000087,
+  0x00000034, 0x0000008e, 0x00000043, 0x00000044,
+  0x000000c4, 0x000000de, 0x000000e9, 0x000000cb,
+  0x00000054, 0x0000007b, 0x00000094, 0x00000032,
+  0x000000a6, 0x000000c2, 0x00000023, 0x0000003d,
+  0x000000ee, 0x0000004c, 0x00000095, 0x0000000b,
+  0x00000042, 0x000000fa, 0x000000c3, 0x0000004e,
+  0x00000008, 0x0000002e, 0x000000a1, 0x00000066,
+  0x00000028, 0x000000d9, 0x00000024, 0x000000b2,
+  0x00000076, 0x0000005b, 0x000000a2, 0x00000049,
+  0x0000006d, 0x0000008b, 0x000000d1, 0x00000025,
+  0x00000072, 0x000000f8, 0x000000f6, 0x00000064,
+  0x00000086, 0x00000068, 0x00000098, 0x00000016,
+  0x000000d4, 0x000000a4, 0x0000005c, 0x000000cc,
+  0x0000005d, 0x00000065, 0x000000b6, 0x00000092,
+  0x0000006c, 0x00000070, 0x00000048, 0x00000050,
+  0x000000fd, 0x000000ed, 0x000000b9, 0x000000da,
+  0x0000005e, 0x00000015, 0x00000046, 0x00000057,
+  0x000000a7, 0x0000008d, 0x0000009d, 0x00000084,
+  0x00000090, 0x000000d8, 0x000000ab, 0x00000000,
+  0x0000008c, 0x000000bc, 0x000000d3, 0x0000000a,
+  0x000000f7, 0x000000e4, 0x00000058, 0x00000005,
+  0x000000b8, 0x000000b3, 0x00000045, 0x00000006,
+  0x000000d0, 0x0000002c, 0x0000001e, 0x0000008f,
+  0x000000ca, 0x0000003f, 0x0000000f, 0x00000002,
+  0x000000c1, 0x000000af, 0x000000bd, 0x00000003,
+  0x00000001, 0x00000013, 0x0000008a, 0x0000006b,
+  0x0000003a, 0x00000091, 0x00000011, 0x00000041,
+  0x0000004f, 0x00000067, 0x000000dc, 0x000000ea,
+  0x00000097, 0x000000f2, 0x000000cf, 0x000000ce,
+  0x000000f0, 0x000000b4, 0x000000e6, 0x00000073,
+  0x00000096, 0x000000ac, 0x00000074, 0x00000022,
+  0x000000e7, 0x000000ad, 0x00000035, 0x00000085,
+  0x000000e2, 0x000000f9, 0x00000037, 0x000000e8,
+  0x0000001c, 0x00000075, 0x000000df, 0x0000006e,
+  0x00000047, 0x000000f1, 0x0000001a, 0x00000071,
+  0x0000001d, 0x00000029, 0x000000c5, 0x00000089,
+  0x0000006f, 0x000000b7, 0x00000062, 0x0000000e,
+  0x000000aa, 0x00000018, 0x000000be, 0x0000001b,
+  0x000000fc, 0x00000056, 0x0000003e, 0x0000004b,
+  0x000000c6, 0x000000d2, 0x00000079, 0x00000020,
+  0x0000009a, 0x000000db, 0x000000c0, 0x000000fe,
+  0x00000078, 0x000000cd, 0x0000005a, 0x000000f4,
+  0x0000001f, 0x000000dd, 0x000000a8, 0x00000033,
+  0x00000088, 0x00000007, 0x000000c7, 0x00000031,
+  0x000000b1, 0x00000012, 0x00000010, 0x00000059,
+  0x00000027, 0x00000080, 0x000000ec, 0x0000005f,
+  0x00000060, 0x00000051, 0x0000007f, 0x000000a9,
+  0x00000019, 0x000000b5, 0x0000004a, 0x0000000d,
+  0x0000002d, 0x000000e5, 0x0000007a, 0x0000009f,
+  0x00000093, 0x000000c9, 0x0000009c, 0x000000ef,
+  0x000000a0, 0x000000e0, 0x0000003b, 0x0000004d,
+  0x000000ae, 0x0000002a, 0x000000f5, 0x000000b0,
+  0x000000c8, 0x000000eb, 0x000000bb, 0x0000003c,
+  0x00000083, 0x00000053, 0x00000099, 0x00000061,
+  0x00000017, 0x0000002b, 0x00000004, 0x0000007e,
+  0x000000ba, 0x00000077, 0x000000d6, 0x00000026,
+  0x000000e1, 0x00000069, 0x00000014, 0x00000063,
+  0x00000055, 0x00000021, 0x0000000c, 0x0000007d
+}, {
+  0x00005200, 0x00000900, 0x00006a00, 0x0000d500,
+  0x00003000, 0x00003600, 0x0000a500, 0x00003800,
+  0x0000bf00, 0x00004000, 0x0000a300, 0x00009e00,
+  0x00008100, 0x0000f300, 0x0000d700, 0x0000fb00,
+  0x00007c00, 0x0000e300, 0x00003900, 0x00008200,
+  0x00009b00, 0x00002f00, 0x0000ff00, 0x00008700,
+  0x00003400, 0x00008e00, 0x00004300, 0x00004400,
+  0x0000c400, 0x0000de00, 0x0000e900, 0x0000cb00,
+  0x00005400, 0x00007b00, 0x00009400, 0x00003200,
+  0x0000a600, 0x0000c200, 0x00002300, 0x00003d00,
+  0x0000ee00, 0x00004c00, 0x00009500, 0x00000b00,
+  0x00004200, 0x0000fa00, 0x0000c300, 0x00004e00,
+  0x00000800, 0x00002e00, 0x0000a100, 0x00006600,
+  0x00002800, 0x0000d900, 0x00002400, 0x0000b200,
+  0x00007600, 0x00005b00, 0x0000a200, 0x00004900,
+  0x00006d00, 0x00008b00, 0x0000d100, 0x00002500,
+  0x00007200, 0x0000f800, 0x0000f600, 0x00006400,
+  0x00008600, 0x00006800, 0x00009800, 0x00001600,
+  0x0000d400, 0x0000a400, 0x00005c00, 0x0000cc00,
+  0x00005d00, 0x00006500, 0x0000b600, 0x00009200,
+  0x00006c00, 0x00007000, 0x00004800, 0x00005000,
+  0x0000fd00, 0x0000ed00, 0x0000b900, 0x0000da00,
+  0x00005e00, 0x00001500, 0x00004600, 0x00005700,
+  0x0000a700, 0x00008d00, 0x00009d00, 0x00008400,
+  0x00009000, 0x0000d800, 0x0000ab00, 0x00000000,
+  0x00008c00, 0x0000bc00, 0x0000d300, 0x00000a00,
+  0x0000f700, 0x0000e400, 0x00005800, 0x00000500,
+  0x0000b800, 0x0000b300, 0x00004500, 0x00000600,
+  0x0000d000, 0x00002c00, 0x00001e00, 0x00008f00,
+  0x0000ca00, 0x00003f00, 0x00000f00, 0x00000200,
+  0x0000c100, 0x0000af00, 0x0000bd00, 0x00000300,
+  0x00000100, 0x00001300, 0x00008a00, 0x00006b00,
+  0x00003a00, 0x00009100, 0x00001100, 0x00004100,
+  0x00004f00, 0x00006700, 0x0000dc00, 0x0000ea00,
+  0x00009700, 0x0000f200, 0x0000cf00, 0x0000ce00,
+  0x0000f000, 0x0000b400, 0x0000e600, 0x00007300,
+  0x00009600, 0x0000ac00, 0x00007400, 0x00002200,
+  0x0000e700, 0x0000ad00, 0x00003500, 0x00008500,
+  0x0000e200, 0x0000f900, 0x00003700, 0x0000e800,
+  0x00001c00, 0x00007500, 0x0000df00, 0x00006e00,
+  0x00004700, 0x0000f100, 0x00001a00, 0x00007100,
+  0x00001d00, 0x00002900, 0x0000c500, 0x00008900,
+  0x00006f00, 0x0000b700, 0x00006200, 0x00000e00,
+  0x0000aa00, 0x00001800, 0x0000be00, 0x00001b00,
+  0x0000fc00, 0x00005600, 0x00003e00, 0x00004b00,
+  0x0000c600, 0x0000d200, 0x00007900, 0x00002000,
+  0x00009a00, 0x0000db00, 0x0000c000, 0x0000fe00,
+  0x00007800, 0x0000cd00, 0x00005a00, 0x0000f400,
+  0x00001f00, 0x0000dd00, 0x0000a800, 0x00003300,
+  0x00008800, 0x00000700, 0x0000c700, 0x00003100,
+  0x0000b100, 0x00001200, 0x00001000, 0x00005900,
+  0x00002700, 0x00008000, 0x0000ec00, 0x00005f00,
+  0x00006000, 0x00005100, 0x00007f00, 0x0000a900,
+  0x00001900, 0x0000b500, 0x00004a00, 0x00000d00,
+  0x00002d00, 0x0000e500, 0x00007a00, 0x00009f00,
+  0x00009300, 0x0000c900, 0x00009c00, 0x0000ef00,
+  0x0000a000, 0x0000e000, 0x00003b00, 0x00004d00,
+  0x0000ae00, 0x00002a00, 0x0000f500, 0x0000b000,
+  0x0000c800, 0x0000eb00, 0x0000bb00, 0x00003c00,
+  0x00008300, 0x00005300, 0x00009900, 0x00006100,
+  0x00001700, 0x00002b00, 0x00000400, 0x00007e00,
+  0x0000ba00, 0x00007700, 0x0000d600, 0x00002600,
+  0x0000e100, 0x00006900, 0x00001400, 0x00006300,
+  0x00005500, 0x00002100, 0x00000c00, 0x00007d00
+}, {
+  0x00520000, 0x00090000, 0x006a0000, 0x00d50000,
+  0x00300000, 0x00360000, 0x00a50000, 0x00380000,
+  0x00bf0000, 0x00400000, 0x00a30000, 0x009e0000,
+  0x00810000, 0x00f30000, 0x00d70000, 0x00fb0000,
+  0x007c0000, 0x00e30000, 0x00390000, 0x00820000,
+  0x009b0000, 0x002f0000, 0x00ff0000, 0x00870000,
+  0x00340000, 0x008e0000, 0x00430000, 0x00440000,
+  0x00c40000, 0x00de0000, 0x00e90000, 0x00cb0000,
+  0x00540000, 0x007b0000, 0x00940000, 0x00320000,
+  0x00a60000, 0x00c20000, 0x00230000, 0x003d0000,
+  0x00ee0000, 0x004c0000, 0x00950000, 0x000b0000,
+  0x00420000, 0x00fa0000, 0x00c30000, 0x004e0000,
+  0x00080000, 0x002e0000, 0x00a10000, 0x00660000,
+  0x00280000, 0x00d90000, 0x00240000, 0x00b20000,
+  0x00760000, 0x005b0000, 0x00a20000, 0x00490000,
+  0x006d0000, 0x008b0000, 0x00d10000, 0x00250000,
+  0x00720000, 0x00f80000, 0x00f60000, 0x00640000,
+  0x00860000, 0x00680000, 0x00980000, 0x00160000,
+  0x00d40000, 0x00a40000, 0x005c0000, 0x00cc0000,
+  0x005d0000, 0x00650000, 0x00b60000, 0x00920000,
+  0x006c0000, 0x00700000, 0x00480000, 0x00500000,
+  0x00fd0000, 0x00ed0000, 0x00b90000, 0x00da0000,
+  0x005e0000, 0x00150000, 0x00460000, 0x00570000,
+  0x00a70000, 0x008d0000, 0x009d0000, 0x00840000,
+  0x00900000, 0x00d80000, 0x00ab0000, 0x00000000,
+  0x008c0000, 0x00bc0000, 0x00d30000, 0x000a0000,
+  0x00f70000, 0x00e40000, 0x00580000, 0x00050000,
+  0x00b80000, 0x00b30000, 0x00450000, 0x00060000,
+  0x00d00000, 0x002c0000, 0x001e0000, 0x008f0000,
+  0x00ca0000, 0x003f0000, 0x000f0000, 0x00020000,
+  0x00c10000, 0x00af0000, 0x00bd0000, 0x00030000,
+  0x00010000, 0x00130000, 0x008a0000, 0x006b0000,
+  0x003a0000, 0x00910000, 0x00110000, 0x00410000,
+  0x004f0000, 0x00670000, 0x00dc0000, 0x00ea0000,
+  0x00970000, 0x00f20000, 0x00cf0000, 0x00ce0000,
+  0x00f00000, 0x00b40000, 0x00e60000, 0x00730000,
+  0x00960000, 0x00ac0000, 0x00740000, 0x00220000,
+  0x00e70000, 0x00ad0000, 0x00350000, 0x00850000,
+  0x00e20000, 0x00f90000, 0x00370000, 0x00e80000,
+  0x001c0000, 0x00750000, 0x00df0000, 0x006e0000,
+  0x00470000, 0x00f10000, 0x001a0000, 0x00710000,
+  0x001d0000, 0x00290000, 0x00c50000, 0x00890000,
+  0x006f0000, 0x00b70000, 0x00620000, 0x000e0000,
+  0x00aa0000, 0x00180000, 0x00be0000, 0x001b0000,
+  0x00fc0000, 0x00560000, 0x003e0000, 0x004b0000,
+  0x00c60000, 0x00d20000, 0x00790000, 0x00200000,
+  0x009a0000, 0x00db0000, 0x00c00000, 0x00fe0000,
+  0x00780000, 0x00cd0000, 0x005a0000, 0x00f40000,
+  0x001f0000, 0x00dd0000, 0x00a80000, 0x00330000,
+  0x00880000, 0x00070000, 0x00c70000, 0x00310000,
+  0x00b10000, 0x00120000, 0x00100000, 0x00590000,
+  0x00270000, 0x00800000, 0x00ec0000, 0x005f0000,
+  0x00600000, 0x00510000, 0x007f0000, 0x00a90000,
+  0x00190000, 0x00b50000, 0x004a0000, 0x000d0000,
+  0x002d0000, 0x00e50000, 0x007a0000, 0x009f0000,
+  0x00930000, 0x00c90000, 0x009c0000, 0x00ef0000,
+  0x00a00000, 0x00e00000, 0x003b0000, 0x004d0000,
+  0x00ae0000, 0x002a0000, 0x00f50000, 0x00b00000,
+  0x00c80000, 0x00eb0000, 0x00bb0000, 0x003c0000,
+  0x00830000, 0x00530000, 0x00990000, 0x00610000,
+  0x00170000, 0x002b0000, 0x00040000, 0x007e0000,
+  0x00ba0000, 0x00770000, 0x00d60000, 0x00260000,
+  0x00e10000, 0x00690000, 0x00140000, 0x00630000,
+  0x00550000, 0x00210000, 0x000c0000, 0x007d0000
+}, {
+  0x52000000, 0x09000000, 0x6a000000, 0xd5000000,
+  0x30000000, 0x36000000, 0xa5000000, 0x38000000,
+  0xbf000000, 0x40000000, 0xa3000000, 0x9e000000,
+  0x81000000, 0xf3000000, 0xd7000000, 0xfb000000,
+  0x7c000000, 0xe3000000, 0x39000000, 0x82000000,
+  0x9b000000, 0x2f000000, 0xff000000, 0x87000000,
+  0x34000000, 0x8e000000, 0x43000000, 0x44000000,
+  0xc4000000, 0xde000000, 0xe9000000, 0xcb000000,
+  0x54000000, 0x7b000000, 0x94000000, 0x32000000,
+  0xa6000000, 0xc2000000, 0x23000000, 0x3d000000,
+  0xee000000, 0x4c000000, 0x95000000, 0x0b000000,
+  0x42000000, 0xfa000000, 0xc3000000, 0x4e000000,
+  0x08000000, 0x2e000000, 0xa1000000, 0x66000000,
+  0x28000000, 0xd9000000, 0x24000000, 0xb2000000,
+  0x76000000, 0x5b000000, 0xa2000000, 0x49000000,
+  0x6d000000, 0x8b000000, 0xd1000000, 0x25000000,
+  0x72000000, 0xf8000000, 0xf6000000, 0x64000000,
+  0x86000000, 0x68000000, 0x98000000, 0x16000000,
+  0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000,
+  0x5d000000, 0x65000000, 0xb6000000, 0x92000000,
+  0x6c000000, 0x70000000, 0x48000000, 0x50000000,
+  0xfd000000, 0xed000000, 0xb9000000, 0xda000000,
+  0x5e000000, 0x15000000, 0x46000000, 0x57000000,
+  0xa7000000, 0x8d000000, 0x9d000000, 0x84000000,
+  0x90000000, 0xd8000000, 0xab000000, 0x00000000,
+  0x8c000000, 0xbc000000, 0xd3000000, 0x0a000000,
+  0xf7000000, 0xe4000000, 0x58000000, 0x05000000,
+  0xb8000000, 0xb3000000, 0x45000000, 0x06000000,
+  0xd0000000, 0x2c000000, 0x1e000000, 0x8f000000,
+  0xca000000, 0x3f000000, 0x0f000000, 0x02000000,
+  0xc1000000, 0xaf000000, 0xbd000000, 0x03000000,
+  0x01000000, 0x13000000, 0x8a000000, 0x6b000000,
+  0x3a000000, 0x91000000, 0x11000000, 0x41000000,
+  0x4f000000, 0x67000000, 0xdc000000, 0xea000000,
+  0x97000000, 0xf2000000, 0xcf000000, 0xce000000,
+  0xf0000000, 0xb4000000, 0xe6000000, 0x73000000,
+  0x96000000, 0xac000000, 0x74000000, 0x22000000,
+  0xe7000000, 0xad000000, 0x35000000, 0x85000000,
+  0xe2000000, 0xf9000000, 0x37000000, 0xe8000000,
+  0x1c000000, 0x75000000, 0xdf000000, 0x6e000000,
+  0x47000000, 0xf1000000, 0x1a000000, 0x71000000,
+  0x1d000000, 0x29000000, 0xc5000000, 0x89000000,
+  0x6f000000, 0xb7000000, 0x62000000, 0x0e000000,
+  0xaa000000, 0x18000000, 0xbe000000, 0x1b000000,
+  0xfc000000, 0x56000000, 0x3e000000, 0x4b000000,
+  0xc6000000, 0xd2000000, 0x79000000, 0x20000000,
+  0x9a000000, 0xdb000000, 0xc0000000, 0xfe000000,
+  0x78000000, 0xcd000000, 0x5a000000, 0xf4000000,
+  0x1f000000, 0xdd000000, 0xa8000000, 0x33000000,
+  0x88000000, 0x07000000, 0xc7000000, 0x31000000,
+  0xb1000000, 0x12000000, 0x10000000, 0x59000000,
+  0x27000000, 0x80000000, 0xec000000, 0x5f000000,
+  0x60000000, 0x51000000, 0x7f000000, 0xa9000000,
+  0x19000000, 0xb5000000, 0x4a000000, 0x0d000000,
+  0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000,
+  0x93000000, 0xc9000000, 0x9c000000, 0xef000000,
+  0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000,
+  0xae000000, 0x2a000000, 0xf5000000, 0xb0000000,
+  0xc8000000, 0xeb000000, 0xbb000000, 0x3c000000,
+  0x83000000, 0x53000000, 0x99000000, 0x61000000,
+  0x17000000, 0x2b000000, 0x04000000, 0x7e000000,
+  0xba000000, 0x77000000, 0xd6000000, 0x26000000,
+  0xe1000000, 0x69000000, 0x14000000, 0x63000000,
+  0x55000000, 0x21000000, 0x0c000000, 0x7d000000
+}
+};
+
+static const u4byte rco_tab[10] = {
+  0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
+  0x00000020, 0x00000040, 0x00000080, 0x0000001b, 0x00000036
+};

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sha1.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c
new file mode 100644
index 0000000..ac406fa
--- /dev/null
+++ b/contrib/pgcrypto/sha1.c
@@ -0,0 +1,341 @@
+/*	   $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $    */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 project nor the names of its contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/sha1.c
+ */
+/*
+ * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
+ * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ * implemented by Jun-ichiro itojun Itoh <it...@itojun.org>
+ */
+
+#include "postgres.h"
+
+#include <sys/param.h>
+
+#include "sha1.h"
+
+/* constant table */
+static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6};
+
+#define K(t)	_K[(t) / 20]
+
+#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
+#define F1(b, c, d) (((b) ^ (c)) ^ (d))
+#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+#define F3(b, c, d) (((b) ^ (c)) ^ (d))
+
+#define S(n, x)		(((x) << (n)) | ((x) >> (32 - (n))))
+
+#define H(n)	(ctxt->h.b32[(n)])
+#define COUNT	(ctxt->count)
+#define BCOUNT	(ctxt->c.b64[0] / 8)
+#define W(n)	(ctxt->m.b32[(n)])
+
+#define PUTBYTE(x) \
+do { \
+	ctxt->m.b8[(COUNT % 64)] = (x);		\
+	COUNT++;				\
+	COUNT %= 64;				\
+	ctxt->c.b64[0] += 8;			\
+	if (COUNT % 64 == 0)			\
+		sha1_step(ctxt);		\
+} while (0)
+
+#define PUTPAD(x) \
+do { \
+	ctxt->m.b8[(COUNT % 64)] = (x);		\
+	COUNT++;				\
+	COUNT %= 64;				\
+	if (COUNT % 64 == 0)			\
+		sha1_step(ctxt);		\
+} while (0)
+
+static void sha1_step(struct sha1_ctxt *);
+
+static void
+sha1_step(struct sha1_ctxt * ctxt)
+{
+	uint32		a,
+				b,
+				c,
+				d,
+				e;
+	size_t		t,
+				s;
+	uint32		tmp;
+
+#ifndef WORDS_BIGENDIAN
+	struct sha1_ctxt tctxt;
+
+	memmove(&tctxt.m.b8[0], &ctxt->m.b8[0], 64);
+	ctxt->m.b8[0] = tctxt.m.b8[3];
+	ctxt->m.b8[1] = tctxt.m.b8[2];
+	ctxt->m.b8[2] = tctxt.m.b8[1];
+	ctxt->m.b8[3] = tctxt.m.b8[0];
+	ctxt->m.b8[4] = tctxt.m.b8[7];
+	ctxt->m.b8[5] = tctxt.m.b8[6];
+	ctxt->m.b8[6] = tctxt.m.b8[5];
+	ctxt->m.b8[7] = tctxt.m.b8[4];
+	ctxt->m.b8[8] = tctxt.m.b8[11];
+	ctxt->m.b8[9] = tctxt.m.b8[10];
+	ctxt->m.b8[10] = tctxt.m.b8[9];
+	ctxt->m.b8[11] = tctxt.m.b8[8];
+	ctxt->m.b8[12] = tctxt.m.b8[15];
+	ctxt->m.b8[13] = tctxt.m.b8[14];
+	ctxt->m.b8[14] = tctxt.m.b8[13];
+	ctxt->m.b8[15] = tctxt.m.b8[12];
+	ctxt->m.b8[16] = tctxt.m.b8[19];
+	ctxt->m.b8[17] = tctxt.m.b8[18];
+	ctxt->m.b8[18] = tctxt.m.b8[17];
+	ctxt->m.b8[19] = tctxt.m.b8[16];
+	ctxt->m.b8[20] = tctxt.m.b8[23];
+	ctxt->m.b8[21] = tctxt.m.b8[22];
+	ctxt->m.b8[22] = tctxt.m.b8[21];
+	ctxt->m.b8[23] = tctxt.m.b8[20];
+	ctxt->m.b8[24] = tctxt.m.b8[27];
+	ctxt->m.b8[25] = tctxt.m.b8[26];
+	ctxt->m.b8[26] = tctxt.m.b8[25];
+	ctxt->m.b8[27] = tctxt.m.b8[24];
+	ctxt->m.b8[28] = tctxt.m.b8[31];
+	ctxt->m.b8[29] = tctxt.m.b8[30];
+	ctxt->m.b8[30] = tctxt.m.b8[29];
+	ctxt->m.b8[31] = tctxt.m.b8[28];
+	ctxt->m.b8[32] = tctxt.m.b8[35];
+	ctxt->m.b8[33] = tctxt.m.b8[34];
+	ctxt->m.b8[34] = tctxt.m.b8[33];
+	ctxt->m.b8[35] = tctxt.m.b8[32];
+	ctxt->m.b8[36] = tctxt.m.b8[39];
+	ctxt->m.b8[37] = tctxt.m.b8[38];
+	ctxt->m.b8[38] = tctxt.m.b8[37];
+	ctxt->m.b8[39] = tctxt.m.b8[36];
+	ctxt->m.b8[40] = tctxt.m.b8[43];
+	ctxt->m.b8[41] = tctxt.m.b8[42];
+	ctxt->m.b8[42] = tctxt.m.b8[41];
+	ctxt->m.b8[43] = tctxt.m.b8[40];
+	ctxt->m.b8[44] = tctxt.m.b8[47];
+	ctxt->m.b8[45] = tctxt.m.b8[46];
+	ctxt->m.b8[46] = tctxt.m.b8[45];
+	ctxt->m.b8[47] = tctxt.m.b8[44];
+	ctxt->m.b8[48] = tctxt.m.b8[51];
+	ctxt->m.b8[49] = tctxt.m.b8[50];
+	ctxt->m.b8[50] = tctxt.m.b8[49];
+	ctxt->m.b8[51] = tctxt.m.b8[48];
+	ctxt->m.b8[52] = tctxt.m.b8[55];
+	ctxt->m.b8[53] = tctxt.m.b8[54];
+	ctxt->m.b8[54] = tctxt.m.b8[53];
+	ctxt->m.b8[55] = tctxt.m.b8[52];
+	ctxt->m.b8[56] = tctxt.m.b8[59];
+	ctxt->m.b8[57] = tctxt.m.b8[58];
+	ctxt->m.b8[58] = tctxt.m.b8[57];
+	ctxt->m.b8[59] = tctxt.m.b8[56];
+	ctxt->m.b8[60] = tctxt.m.b8[63];
+	ctxt->m.b8[61] = tctxt.m.b8[62];
+	ctxt->m.b8[62] = tctxt.m.b8[61];
+	ctxt->m.b8[63] = tctxt.m.b8[60];
+#endif
+
+	a = H(0);
+	b = H(1);
+	c = H(2);
+	d = H(3);
+	e = H(4);
+
+	for (t = 0; t < 20; t++)
+	{
+		s = t & 0x0f;
+		if (t >= 16)
+			W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
+		tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
+		e = d;
+		d = c;
+		c = S(30, b);
+		b = a;
+		a = tmp;
+	}
+	for (t = 20; t < 40; t++)
+	{
+		s = t & 0x0f;
+		W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
+		tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
+		e = d;
+		d = c;
+		c = S(30, b);
+		b = a;
+		a = tmp;
+	}
+	for (t = 40; t < 60; t++)
+	{
+		s = t & 0x0f;
+		W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
+		tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
+		e = d;
+		d = c;
+		c = S(30, b);
+		b = a;
+		a = tmp;
+	}
+	for (t = 60; t < 80; t++)
+	{
+		s = t & 0x0f;
+		W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s));
+		tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
+		e = d;
+		d = c;
+		c = S(30, b);
+		b = a;
+		a = tmp;
+	}
+
+	H(0) = H(0) + a;
+	H(1) = H(1) + b;
+	H(2) = H(2) + c;
+	H(3) = H(3) + d;
+	H(4) = H(4) + e;
+
+	memset(&ctxt->m.b8[0], 0, 64);
+}
+
+/*------------------------------------------------------------*/
+
+void
+sha1_init(struct sha1_ctxt * ctxt)
+{
+	memset(ctxt, 0, sizeof(struct sha1_ctxt));
+	H(0) = 0x67452301;
+	H(1) = 0xefcdab89;
+	H(2) = 0x98badcfe;
+	H(3) = 0x10325476;
+	H(4) = 0xc3d2e1f0;
+}
+
+void
+sha1_pad(struct sha1_ctxt * ctxt)
+{
+	size_t		padlen;			/* pad length in bytes */
+	size_t		padstart;
+
+	PUTPAD(0x80);
+
+	padstart = COUNT % 64;
+	padlen = 64 - padstart;
+	if (padlen < 8)
+	{
+		memset(&ctxt->m.b8[padstart], 0, padlen);
+		COUNT += padlen;
+		COUNT %= 64;
+		sha1_step(ctxt);
+		padstart = COUNT % 64;	/* should be 0 */
+		padlen = 64 - padstart; /* should be 64 */
+	}
+	memset(&ctxt->m.b8[padstart], 0, padlen - 8);
+	COUNT += (padlen - 8);
+	COUNT %= 64;
+#ifdef WORDS_BIGENDIAN
+	PUTPAD(ctxt->c.b8[0]);
+	PUTPAD(ctxt->c.b8[1]);
+	PUTPAD(ctxt->c.b8[2]);
+	PUTPAD(ctxt->c.b8[3]);
+	PUTPAD(ctxt->c.b8[4]);
+	PUTPAD(ctxt->c.b8[5]);
+	PUTPAD(ctxt->c.b8[6]);
+	PUTPAD(ctxt->c.b8[7]);
+#else
+	PUTPAD(ctxt->c.b8[7]);
+	PUTPAD(ctxt->c.b8[6]);
+	PUTPAD(ctxt->c.b8[5]);
+	PUTPAD(ctxt->c.b8[4]);
+	PUTPAD(ctxt->c.b8[3]);
+	PUTPAD(ctxt->c.b8[2]);
+	PUTPAD(ctxt->c.b8[1]);
+	PUTPAD(ctxt->c.b8[0]);
+#endif
+}
+
+void
+sha1_loop(struct sha1_ctxt * ctxt, const uint8 *input0, size_t len)
+{
+	const uint8 *input;
+	size_t		gaplen;
+	size_t		gapstart;
+	size_t		off;
+	size_t		copysiz;
+
+	input = (const uint8 *) input0;
+	off = 0;
+
+	while (off < len)
+	{
+		gapstart = COUNT % 64;
+		gaplen = 64 - gapstart;
+
+		copysiz = (gaplen < len - off) ? gaplen : len - off;
+		memmove(&ctxt->m.b8[gapstart], &input[off], copysiz);
+		COUNT += copysiz;
+		COUNT %= 64;
+		ctxt->c.b64[0] += copysiz * 8;
+		if (COUNT % 64 == 0)
+			sha1_step(ctxt);
+		off += copysiz;
+	}
+}
+
+void
+sha1_result(struct sha1_ctxt * ctxt, uint8 *digest0)
+{
+	uint8	   *digest;
+
+	digest = (uint8 *) digest0;
+	sha1_pad(ctxt);
+#ifdef WORDS_BIGENDIAN
+	memmove(digest, &ctxt->h.b8[0], 20);
+#else
+	digest[0] = ctxt->h.b8[3];
+	digest[1] = ctxt->h.b8[2];
+	digest[2] = ctxt->h.b8[1];
+	digest[3] = ctxt->h.b8[0];
+	digest[4] = ctxt->h.b8[7];
+	digest[5] = ctxt->h.b8[6];
+	digest[6] = ctxt->h.b8[5];
+	digest[7] = ctxt->h.b8[4];
+	digest[8] = ctxt->h.b8[11];
+	digest[9] = ctxt->h.b8[10];
+	digest[10] = ctxt->h.b8[9];
+	digest[11] = ctxt->h.b8[8];
+	digest[12] = ctxt->h.b8[15];
+	digest[13] = ctxt->h.b8[14];
+	digest[14] = ctxt->h.b8[13];
+	digest[15] = ctxt->h.b8[12];
+	digest[16] = ctxt->h.b8[19];
+	digest[17] = ctxt->h.b8[18];
+	digest[18] = ctxt->h.b8[17];
+	digest[19] = ctxt->h.b8[16];
+#endif
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/sha1.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/sha1.h b/contrib/pgcrypto/sha1.h
new file mode 100644
index 0000000..3e0931e
--- /dev/null
+++ b/contrib/pgcrypto/sha1.h
@@ -0,0 +1,75 @@
+/*	contrib/pgcrypto/sha1.h */
+/*	   $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $    */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 project nor the names of its contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
+ * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ * implemented by Jun-ichiro itojun Itoh <it...@itojun.org>
+ */
+
+#ifndef _NETINET6_SHA1_H_
+#define _NETINET6_SHA1_H_
+
+struct sha1_ctxt
+{
+	union
+	{
+		uint8		b8[20];
+		uint32		b32[5];
+	}			h;
+	union
+	{
+		uint8		b8[8];
+		uint64		b64[1];
+	}			c;
+	union
+	{
+		uint8		b8[64];
+		uint32		b32[16];
+	}			m;
+	uint8		count;
+};
+
+extern void sha1_init(struct sha1_ctxt *);
+extern void sha1_pad(struct sha1_ctxt *);
+extern void sha1_loop(struct sha1_ctxt *, const uint8 *, size_t);
+extern void sha1_result(struct sha1_ctxt *, uint8 *);
+
+/* compatibilty with other SHA1 source codes */
+typedef struct sha1_ctxt SHA1_CTX;
+
+#define SHA1Init(x)		sha1_init((x))
+#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
+#define SHA1Final(x, y)		sha1_result((y), (x))
+
+#define SHA1_RESULTLEN	(160/8)
+
+#endif   /* _NETINET6_SHA1_H_ */


[13/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
HAWQ-1007. Add the pgcrypto code into hawq


Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/801100ed
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/801100ed
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/801100ed

Branch: refs/heads/master
Commit: 801100edd78cb55ac82b9989ef7b94ae86ae89d4
Parents: 3278633
Author: Paul Guo <pa...@gmail.com>
Authored: Tue Aug 16 14:55:39 2016 +0800
Committer: Paul Guo <pa...@gmail.com>
Committed: Wed Sep 7 09:23:42 2016 +0800

----------------------------------------------------------------------
 contrib/.gitignore                              |    1 -
 contrib/Makefile                                |   24 +-
 contrib/pgcrypto                                |    1 -
 contrib/pgcrypto.patch                          |  287 --
 contrib/pgcrypto/.gitignore                     |    5 +
 contrib/pgcrypto/Makefile                       |   66 +
 contrib/pgcrypto/blf.c                          |  499 +++
 contrib/pgcrypto/blf.h                          |   46 +
 contrib/pgcrypto/crypt-blowfish.c               |  735 ++++
 contrib/pgcrypto/crypt-des.c                    |  774 ++++
 contrib/pgcrypto/crypt-gensalt.c                |  187 +
 contrib/pgcrypto/crypt-md5.c                    |  163 +
 contrib/pgcrypto/expected/3des.out              |   71 +
 contrib/pgcrypto/expected/blowfish.out          |  175 +
 contrib/pgcrypto/expected/cast5.out             |   88 +
 contrib/pgcrypto/expected/crypt-blowfish.out    |   27 +
 contrib/pgcrypto/expected/crypt-des.out         |   27 +
 contrib/pgcrypto/expected/crypt-md5.out         |   27 +
 contrib/pgcrypto/expected/crypt-xdes.out        |   27 +
 contrib/pgcrypto/expected/des.out               |   63 +
 contrib/pgcrypto/expected/hmac-md5.out          |   72 +
 contrib/pgcrypto/expected/hmac-sha1.out         |   72 +
 contrib/pgcrypto/expected/init.out              |   28 +
 contrib/pgcrypto/expected/md5.out               |   45 +
 contrib/pgcrypto/expected/pgp-armor.out         |  104 +
 contrib/pgcrypto/expected/pgp-compression.out   |   50 +
 contrib/pgcrypto/expected/pgp-decrypt.out       |  366 ++
 .../pgcrypto/expected/pgp-encrypt-DISABLED.out  |    1 +
 contrib/pgcrypto/expected/pgp-encrypt.out       |  191 +
 contrib/pgcrypto/expected/pgp-info.out          |   78 +
 .../pgcrypto/expected/pgp-pubkey-DISABLED.out   |    1 +
 .../pgcrypto/expected/pgp-pubkey-decrypt.out    |  555 +++
 .../pgcrypto/expected/pgp-pubkey-encrypt.out    |   70 +
 contrib/pgcrypto/expected/pgp-zlib-DISABLED.out |    1 +
 contrib/pgcrypto/expected/rijndael.out          |  126 +
 contrib/pgcrypto/expected/sha1.out              |   45 +
 contrib/pgcrypto/expected/sha2.out              |  139 +
 contrib/pgcrypto/fortuna.c                      |  462 +++
 contrib/pgcrypto/fortuna.h                      |   38 +
 contrib/pgcrypto/imath.c                        | 3681 ++++++++++++++++++
 contrib/pgcrypto/imath.h                        |  217 ++
 contrib/pgcrypto/internal-sha2.c                |  316 ++
 contrib/pgcrypto/internal.c                     |  688 ++++
 contrib/pgcrypto/mbuf.c                         |  563 +++
 contrib/pgcrypto/mbuf.h                         |  124 +
 contrib/pgcrypto/md5.c                          |  397 ++
 contrib/pgcrypto/md5.h                          |   79 +
 contrib/pgcrypto/openssl.c                      | 1032 +++++
 contrib/pgcrypto/pgcrypto--1.0.sql              |  202 +
 contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql  |   38 +
 contrib/pgcrypto/pgcrypto.c                     |  469 +++
 contrib/pgcrypto/pgcrypto.control               |    5 +
 contrib/pgcrypto/pgcrypto.h                     |   49 +
 contrib/pgcrypto/pgcrypto.sql.in                |  203 +
 contrib/pgcrypto/pgp-armor.c                    |  383 ++
 contrib/pgcrypto/pgp-cfb.c                      |  265 ++
 contrib/pgcrypto/pgp-compress.c                 |  329 ++
 contrib/pgcrypto/pgp-decrypt.c                  | 1188 ++++++
 contrib/pgcrypto/pgp-encrypt.c                  |  708 ++++
 contrib/pgcrypto/pgp-info.c                     |  235 ++
 contrib/pgcrypto/pgp-mpi-internal.c             |  308 ++
 contrib/pgcrypto/pgp-mpi-openssl.c              |  285 ++
 contrib/pgcrypto/pgp-mpi.c                      |  143 +
 contrib/pgcrypto/pgp-pgsql.c                    |  919 +++++
 contrib/pgcrypto/pgp-pubdec.c                   |  236 ++
 contrib/pgcrypto/pgp-pubenc.c                   |  250 ++
 contrib/pgcrypto/pgp-pubkey.c                   |  584 +++
 contrib/pgcrypto/pgp-s2k.c                      |  296 ++
 contrib/pgcrypto/pgp.c                          |  360 ++
 contrib/pgcrypto/pgp.h                          |  314 ++
 contrib/pgcrypto/px-crypt.c                     |  167 +
 contrib/pgcrypto/px-crypt.h                     |   82 +
 contrib/pgcrypto/px-hmac.c                      |  177 +
 contrib/pgcrypto/px.c                           |  437 +++
 contrib/pgcrypto/px.h                           |  250 ++
 contrib/pgcrypto/random.c                       |  244 ++
 contrib/pgcrypto/rijndael.c                     |  677 ++++
 contrib/pgcrypto/rijndael.h                     |   60 +
 contrib/pgcrypto/rijndael.tbl                   | 1138 ++++++
 contrib/pgcrypto/sha1.c                         |  341 ++
 contrib/pgcrypto/sha1.h                         |   75 +
 contrib/pgcrypto/sha2.c                         |  991 +++++
 contrib/pgcrypto/sha2.h                         |  100 +
 contrib/pgcrypto/sql/3des.sql                   |   31 +
 contrib/pgcrypto/sql/blowfish.sql               |   92 +
 contrib/pgcrypto/sql/cast5.sql                  |   47 +
 contrib/pgcrypto/sql/crypt-blowfish.sql         |   17 +
 contrib/pgcrypto/sql/crypt-des.sql              |   17 +
 contrib/pgcrypto/sql/crypt-md5.sql              |   17 +
 contrib/pgcrypto/sql/crypt-xdes.sql             |   17 +
 contrib/pgcrypto/sql/des.sql                    |   29 +
 contrib/pgcrypto/sql/hmac-md5.sql               |   44 +
 contrib/pgcrypto/sql/hmac-sha1.sql              |   44 +
 contrib/pgcrypto/sql/init.sql                   |   18 +
 contrib/pgcrypto/sql/md5.sql                    |   11 +
 contrib/pgcrypto/sql/pgp-armor.sql              |   58 +
 contrib/pgcrypto/sql/pgp-compression.sql        |   30 +
 contrib/pgcrypto/sql/pgp-decrypt.sql            |  266 ++
 contrib/pgcrypto/sql/pgp-encrypt-DISABLED.sql   |    1 +
 contrib/pgcrypto/sql/pgp-encrypt.sql            |   97 +
 contrib/pgcrypto/sql/pgp-info.sql               |   22 +
 contrib/pgcrypto/sql/pgp-pubkey-DISABLED.sql    |    1 +
 contrib/pgcrypto/sql/pgp-pubkey-decrypt.sql     |  548 +++
 contrib/pgcrypto/sql/pgp-pubkey-encrypt.sql     |   50 +
 contrib/pgcrypto/sql/pgp-zlib-DISABLED.sql      |    1 +
 contrib/pgcrypto/sql/rijndael.sql               |   63 +
 contrib/pgcrypto/sql/sha1.sql                   |   11 +
 contrib/pgcrypto/sql/sha2.sql                   |   33 +
 contrib/pgcrypto/uninstall_pgcrypto.sql         |   46 +
 depends/thirdparty/.gitignore                   |    1 -
 depends/thirdparty/README                       |    5 +-
 depends/thirdparty/postgres.commit              |    1 -
 112 files changed, 26643 insertions(+), 317 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/.gitignore
----------------------------------------------------------------------
diff --git a/contrib/.gitignore b/contrib/.gitignore
deleted file mode 100644
index 2971e1e..0000000
--- a/contrib/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-pgcrypto_prepare_timestamp

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/Makefile
----------------------------------------------------------------------
diff --git a/contrib/Makefile b/contrib/Makefile
index 1da02f6..a75d930 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -13,35 +13,13 @@ WANTED_DIRS = \
 
 ifeq ($(with_pgcrypto), yes)
 WANTED_DIRS += pgcrypto
-
-pgcrypto_commit := $(shell cat $(abs_top_srcdir)/depends/thirdparty/postgres.commit)
-
-pgcrypto_prepare_timestamp: pgcrypto.patch $(abs_top_srcdir)/depends/thirdparty/postgres.commit
-	rm -f pgcrypto_prepare_timestamp
-
-# This includes an ugly hack which remove two added files after "git-reset".
-# I do this because "git apply" fails if the two files have existed.
-pgcrypto_prepare: pgcrypto_prepare_timestamp
-	if [ ! -f $(abs_top_builddir)/$(subdir)/pgcrypto_prepare_timestamp ]; then \
-		[ "x$(pgcrypto_commit)" != "x" ] || exit 1; \
-		cd $(abs_top_srcdir)/depends/thirdparty; mkdir -p postgres; cd postgres; \
-		[ ! -d .git ] && git clone https://github.com/postgres/postgres.git .; \
-		git reset --hard $(pgcrypto_commit) || (echo Now fetch from upstream and try again; git fetch origin master; git reset --hard $(pgcrypto_commit)) || exit 2; \
-		rm -f contrib/pgcrypto/pgcrypto.sql.in contrib/pgcrypto/uninstall_pgcrypto.sql; \
-		git apply $(abs_top_srcdir)/$(subdir)/pgcrypto.patch || exit 3; \
-		touch $(abs_top_builddir)/$(subdir)/pgcrypto_prepare_timestamp; \
-	fi
-else
-pgcrypto_prepare:
 endif
 
-.PHONY: pgcrypto_prepare
-
 # Missing:
 #		start-scripts	\ (does not have a makefile)
 #		xml2		\ (requires libxml installed)
 
-all install installdirs uninstall distprep: pgcrypto_prepare
+all install installdirs uninstall distprep:
 	@for dir in $(WANTED_DIRS); do \
 		$(MAKE) -C $$dir $@ || exit; \
 	done


[05/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-mpi.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-mpi.c b/contrib/pgcrypto/pgp-mpi.c
new file mode 100644
index 0000000..c8765b6
--- /dev/null
+++ b/contrib/pgcrypto/pgp-mpi.c
@@ -0,0 +1,143 @@
+/*
+ * pgp-mpi.c
+ *	  OpenPGP MPI helper functions.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-mpi.c
+ */
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+int
+pgp_mpi_alloc(int bits, PGP_MPI **mpi)
+{
+	PGP_MPI    *n;
+	int			len = (bits + 7) / 8;
+
+	if (bits < 0 || bits > 0xFFFF)
+	{
+		px_debug("pgp_mpi_alloc: unreasonable request: bits=%d", bits);
+		return PXE_PGP_CORRUPT_DATA;
+	}
+	n = px_alloc(sizeof(*n) + len);
+	n->bits = bits;
+	n->bytes = len;
+	n->data = (uint8 *) (n) + sizeof(*n);
+	*mpi = n;
+	return 0;
+}
+
+int
+pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi)
+{
+	int			res;
+	PGP_MPI    *n;
+
+	res = pgp_mpi_alloc(bits, &n);
+	if (res < 0)
+		return res;
+	memcpy(n->data, data, n->bytes);
+	*mpi = n;
+	return 0;
+}
+
+int
+pgp_mpi_free(PGP_MPI *mpi)
+{
+	if (mpi == NULL)
+		return 0;
+	memset(mpi, 0, sizeof(*mpi) + mpi->bytes);
+	px_free(mpi);
+	return 0;
+}
+
+int
+pgp_mpi_read(PullFilter *src, PGP_MPI **mpi)
+{
+	int			res;
+	uint8		hdr[2];
+	int			bits;
+	PGP_MPI    *n;
+
+	res = pullf_read_fixed(src, 2, hdr);
+	if (res < 0)
+		return res;
+	bits = ((unsigned) hdr[0] << 8) + hdr[1];
+
+	res = pgp_mpi_alloc(bits, &n);
+	if (res < 0)
+		return res;
+
+	res = pullf_read_fixed(src, n->bytes, n->data);
+	if (res < 0)
+		pgp_mpi_free(n);
+	else
+		*mpi = n;
+	return res;
+}
+
+int
+pgp_mpi_write(PushFilter *dst, PGP_MPI *n)
+{
+	int			res;
+	uint8		buf[2];
+
+	buf[0] = n->bits >> 8;
+	buf[1] = n->bits & 0xFF;
+	res = pushf_write(dst, buf, 2);
+	if (res >= 0)
+		res = pushf_write(dst, n->data, n->bytes);
+	return res;
+}
+
+int
+pgp_mpi_hash(PX_MD *md, PGP_MPI *n)
+{
+	uint8		buf[2];
+
+	buf[0] = n->bits >> 8;
+	buf[1] = n->bits & 0xFF;
+	px_md_update(md, buf, 2);
+	px_md_update(md, n->data, n->bytes);
+
+	return 0;
+}
+
+unsigned
+pgp_mpi_cksum(unsigned cksum, PGP_MPI *n)
+{
+	int			i;
+
+	cksum += n->bits >> 8;
+	cksum += n->bits & 0xFF;
+	for (i = 0; i < n->bytes; i++)
+		cksum += n->data[i];
+
+	return cksum & 0xFFFF;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-pgsql.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c
new file mode 100644
index 0000000..d4eec03
--- /dev/null
+++ b/contrib/pgcrypto/pgp-pgsql.c
@@ -0,0 +1,919 @@
+/*
+ * pgp-pgsql.c
+ *		PostgreSQL wrappers for pgp.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-pgsql.c
+ */
+
+#include "postgres.h"
+
+#include "mb/pg_wchar.h"
+#include "utils/builtins.h"
+
+#include "mbuf.h"
+#include "px.h"
+#include "pgp.h"
+
+/*
+ * public functions
+ */
+Datum		pgp_sym_encrypt_text(PG_FUNCTION_ARGS);
+Datum		pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS);
+Datum		pgp_sym_decrypt_text(PG_FUNCTION_ARGS);
+Datum		pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS);
+
+Datum		pgp_pub_encrypt_text(PG_FUNCTION_ARGS);
+Datum		pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS);
+Datum		pgp_pub_decrypt_text(PG_FUNCTION_ARGS);
+Datum		pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS);
+
+Datum		pgp_key_id_w(PG_FUNCTION_ARGS);
+
+Datum		pg_armor(PG_FUNCTION_ARGS);
+Datum		pg_dearmor(PG_FUNCTION_ARGS);
+
+/* function headers */
+
+PG_FUNCTION_INFO_V1(pgp_sym_encrypt_bytea);
+PG_FUNCTION_INFO_V1(pgp_sym_encrypt_text);
+PG_FUNCTION_INFO_V1(pgp_sym_decrypt_bytea);
+PG_FUNCTION_INFO_V1(pgp_sym_decrypt_text);
+
+PG_FUNCTION_INFO_V1(pgp_pub_encrypt_bytea);
+PG_FUNCTION_INFO_V1(pgp_pub_encrypt_text);
+PG_FUNCTION_INFO_V1(pgp_pub_decrypt_bytea);
+PG_FUNCTION_INFO_V1(pgp_pub_decrypt_text);
+
+PG_FUNCTION_INFO_V1(pgp_key_id_w);
+
+PG_FUNCTION_INFO_V1(pg_armor);
+PG_FUNCTION_INFO_V1(pg_dearmor);
+
+/*
+ * Mix a block of data into RNG.
+ */
+static void
+add_block_entropy(PX_MD *md, text *data)
+{
+	uint8		sha1[20];
+
+	px_md_reset(md);
+	px_md_update(md, (uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ);
+	px_md_finish(md, sha1);
+
+	px_add_entropy(sha1, 20);
+
+	memset(sha1, 0, 20);
+}
+
+/*
+ * Mix user data into RNG.	It is for user own interests to have
+ * RNG state shuffled.
+ */
+static void
+add_entropy(text *data1, text *data2, text *data3)
+{
+	PX_MD	   *md;
+	uint8		rnd[3];
+
+	if (!data1 && !data2 && !data3)
+		return;
+
+	if (px_get_random_bytes(rnd, 3) < 0)
+		return;
+
+	if (px_find_digest("sha1", &md) < 0)
+		return;
+
+	/*
+	 * Try to make the feeding unpredictable.
+	 *
+	 * Prefer data over keys, as it's rather likely that key is same in
+	 * several calls.
+	 */
+
+	/* chance: 7/8 */
+	if (data1 && rnd[0] >= 32)
+		add_block_entropy(md, data1);
+
+	/* chance: 5/8 */
+	if (data2 && rnd[1] >= 160)
+		add_block_entropy(md, data2);
+
+	/* chance: 5/8 */
+	if (data3 && rnd[2] >= 160)
+		add_block_entropy(md, data3);
+
+	px_md_free(md);
+	memset(rnd, 0, sizeof(rnd));
+}
+
+/*
+ * returns src in case of no conversion or error
+ */
+static text *
+convert_charset(text *src, int cset_from, int cset_to)
+{
+	int			src_len = VARSIZE(src) - VARHDRSZ;
+	unsigned char *dst;
+	unsigned char *csrc = (unsigned char *) VARDATA(src);
+	text	   *res;
+
+	dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to);
+	if (dst == csrc)
+		return src;
+
+	res = cstring_to_text((char *) dst);
+	pfree(dst);
+	return res;
+}
+
+static text *
+convert_from_utf8(text *src)
+{
+	return convert_charset(src, PG_UTF8, GetDatabaseEncoding());
+}
+
+static text *
+convert_to_utf8(text *src)
+{
+	return convert_charset(src, GetDatabaseEncoding(), PG_UTF8);
+}
+
+static void
+clear_and_pfree(text *p)
+{
+	memset(p, 0, VARSIZE(p));
+	pfree(p);
+}
+
+/*
+ * expect-* arguments storage
+ */
+struct debug_expect
+{
+	int			debug;
+	int			expect;
+	int			cipher_algo;
+	int			s2k_mode;
+	int			s2k_cipher_algo;
+	int			s2k_digest_algo;
+	int			compress_algo;
+	int			use_sess_key;
+	int			disable_mdc;
+	int			unicode_mode;
+};
+
+static void
+fill_expect(struct debug_expect * ex, int text_mode)
+{
+	ex->debug = 0;
+	ex->expect = 0;
+	ex->cipher_algo = -1;
+	ex->s2k_mode = -1;
+	ex->s2k_cipher_algo = -1;
+	ex->s2k_digest_algo = -1;
+	ex->compress_algo = -1;
+	ex->use_sess_key = -1;
+	ex->disable_mdc = -1;
+	ex->unicode_mode = -1;
+}
+
+#define EX_MSG(arg) \
+	ereport(NOTICE, (errmsg( \
+		"pgp_decrypt: unexpected %s: expected %d got %d", \
+		CppAsString(arg), ex->arg, ctx->arg)))
+
+#define EX_CHECK(arg) do { \
+		if (ex->arg >= 0 && ex->arg != ctx->arg) EX_MSG(arg); \
+	} while (0)
+
+static void
+check_expect(PGP_Context *ctx, struct debug_expect * ex)
+{
+	EX_CHECK(cipher_algo);
+	EX_CHECK(s2k_mode);
+	EX_CHECK(s2k_digest_algo);
+	EX_CHECK(use_sess_key);
+	if (ctx->use_sess_key)
+		EX_CHECK(s2k_cipher_algo);
+	EX_CHECK(disable_mdc);
+	EX_CHECK(compress_algo);
+	EX_CHECK(unicode_mode);
+}
+
+static void
+show_debug(const char *msg)
+{
+	ereport(NOTICE, (errmsg("dbg: %s", msg)));
+}
+
+static int
+set_arg(PGP_Context *ctx, char *key, char *val,
+		struct debug_expect * ex)
+{
+	int			res = 0;
+
+	if (strcmp(key, "cipher-algo") == 0)
+		res = pgp_set_cipher_algo(ctx, val);
+	else if (strcmp(key, "disable-mdc") == 0)
+		res = pgp_disable_mdc(ctx, atoi(val));
+	else if (strcmp(key, "sess-key") == 0)
+		res = pgp_set_sess_key(ctx, atoi(val));
+	else if (strcmp(key, "s2k-mode") == 0)
+		res = pgp_set_s2k_mode(ctx, atoi(val));
+	else if (strcmp(key, "s2k-digest-algo") == 0)
+		res = pgp_set_s2k_digest_algo(ctx, val);
+	else if (strcmp(key, "s2k-cipher-algo") == 0)
+		res = pgp_set_s2k_cipher_algo(ctx, val);
+	else if (strcmp(key, "compress-algo") == 0)
+		res = pgp_set_compress_algo(ctx, atoi(val));
+	else if (strcmp(key, "compress-level") == 0)
+		res = pgp_set_compress_level(ctx, atoi(val));
+	else if (strcmp(key, "convert-crlf") == 0)
+		res = pgp_set_convert_crlf(ctx, atoi(val));
+	else if (strcmp(key, "unicode-mode") == 0)
+		res = pgp_set_unicode_mode(ctx, atoi(val));
+	/* decrypt debug */
+	else if (ex != NULL && strcmp(key, "debug") == 0)
+		ex->debug = atoi(val);
+	else if (ex != NULL && strcmp(key, "expect-cipher-algo") == 0)
+	{
+		ex->expect = 1;
+		ex->cipher_algo = pgp_get_cipher_code(val);
+	}
+	else if (ex != NULL && strcmp(key, "expect-disable-mdc") == 0)
+	{
+		ex->expect = 1;
+		ex->disable_mdc = atoi(val);
+	}
+	else if (ex != NULL && strcmp(key, "expect-sess-key") == 0)
+	{
+		ex->expect = 1;
+		ex->use_sess_key = atoi(val);
+	}
+	else if (ex != NULL && strcmp(key, "expect-s2k-mode") == 0)
+	{
+		ex->expect = 1;
+		ex->s2k_mode = atoi(val);
+	}
+	else if (ex != NULL && strcmp(key, "expect-s2k-digest-algo") == 0)
+	{
+		ex->expect = 1;
+		ex->s2k_digest_algo = pgp_get_digest_code(val);
+	}
+	else if (ex != NULL && strcmp(key, "expect-s2k-cipher-algo") == 0)
+	{
+		ex->expect = 1;
+		ex->s2k_cipher_algo = pgp_get_cipher_code(val);
+	}
+	else if (ex != NULL && strcmp(key, "expect-compress-algo") == 0)
+	{
+		ex->expect = 1;
+		ex->compress_algo = atoi(val);
+	}
+	else if (ex != NULL && strcmp(key, "expect-unicode-mode") == 0)
+	{
+		ex->expect = 1;
+		ex->unicode_mode = atoi(val);
+	}
+	else
+		res = PXE_ARGUMENT_ERROR;
+
+	return res;
+}
+
+/*
+ * Find next word.	Handle ',' and '=' as words.  Skip whitespace.
+ * Put word info into res_p, res_len.
+ * Returns ptr to next word.
+ */
+static char *
+getword(char *p, char **res_p, int *res_len)
+{
+	/* whitespace at start */
+	while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
+		p++;
+
+	/* word data */
+	*res_p = p;
+	if (*p == '=' || *p == ',')
+		p++;
+	else
+		while (*p && !(*p == ' ' || *p == '\t' || *p == '\n'
+					   || *p == '=' || *p == ','))
+			p++;
+
+	/* word end */
+	*res_len = p - *res_p;
+
+	/* whitespace at end */
+	while (*p && (*p == ' ' || *p == '\t' || *p == '\n'))
+		p++;
+
+	return p;
+}
+
+/*
+ * Convert to lowercase asciiz string.
+ */
+static char *
+downcase_convert(const uint8 *s, int len)
+{
+	int			c,
+				i;
+	char	   *res = palloc(len + 1);
+
+	for (i = 0; i < len; i++)
+	{
+		c = s[i];
+		if (c >= 'A' && c <= 'Z')
+			c += 'a' - 'A';
+		res[i] = c;
+	}
+	res[len] = 0;
+	return res;
+}
+
+static int
+parse_args(PGP_Context *ctx, uint8 *args, int arg_len,
+		   struct debug_expect * ex)
+{
+	char	   *str = downcase_convert(args, arg_len);
+	char	   *key,
+			   *val;
+	int			key_len,
+				val_len;
+	int			res = 0;
+	char	   *p = str;
+
+	while (*p)
+	{
+		res = PXE_ARGUMENT_ERROR;
+		p = getword(p, &key, &key_len);
+		if (*p++ != '=')
+			break;
+		p = getword(p, &val, &val_len);
+		if (*p == '\0')
+			;
+		else if (*p++ != ',')
+			break;
+
+		if (*key == 0 || *val == 0 || val_len == 0)
+			break;
+
+		key[key_len] = 0;
+		val[val_len] = 0;
+
+		res = set_arg(ctx, key, val, ex);
+		if (res < 0)
+			break;
+	}
+	pfree(str);
+	return res;
+}
+
+static MBuf *
+create_mbuf_from_vardata(text *data)
+{
+	return mbuf_create_from_data((uint8 *) VARDATA(data),
+								 VARSIZE(data) - VARHDRSZ);
+}
+
+static void
+init_work(PGP_Context **ctx_p, int is_text,
+		  text *args, struct debug_expect * ex)
+{
+	int			err = pgp_init(ctx_p);
+
+	fill_expect(ex, is_text);
+
+	if (err == 0 && args != NULL)
+		err = parse_args(*ctx_p, (uint8 *) VARDATA(args),
+						 VARSIZE(args) - VARHDRSZ, ex);
+
+	if (err)
+	{
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("%s", px_strerror(err))));
+	}
+
+	if (ex->debug)
+		px_set_debug_handler(show_debug);
+
+	pgp_set_text_mode(*ctx_p, is_text);
+}
+
+static bytea *
+encrypt_internal(int is_pubenc, int is_text,
+				 text *data, text *key, text *args)
+{
+	MBuf	   *src,
+			   *dst;
+	uint8		tmp[VARHDRSZ];
+	uint8	   *restmp;
+	bytea	   *res;
+	int			res_len;
+	PGP_Context *ctx;
+	int			err;
+	struct debug_expect ex;
+	text	   *tmp_data = NULL;
+
+	/*
+	 * Add data and key info RNG.
+	 */
+	add_entropy(data, key, NULL);
+
+	init_work(&ctx, is_text, args, &ex);
+
+	if (is_text && pgp_get_unicode_mode(ctx))
+	{
+		tmp_data = convert_to_utf8(data);
+		if (tmp_data == data)
+			tmp_data = NULL;
+		else
+			data = tmp_data;
+	}
+
+	src = create_mbuf_from_vardata(data);
+	dst = mbuf_create(VARSIZE(data) + 128);
+
+	/*
+	 * reserve room for header
+	 */
+	mbuf_append(dst, tmp, VARHDRSZ);
+
+	/*
+	 * set key
+	 */
+	if (is_pubenc)
+	{
+		MBuf	   *kbuf = create_mbuf_from_vardata(key);
+
+		err = pgp_set_pubkey(ctx, kbuf,
+							 NULL, 0, 0);
+		mbuf_free(kbuf);
+	}
+	else
+		err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
+							 VARSIZE(key) - VARHDRSZ);
+
+	/*
+	 * encrypt
+	 */
+	if (err >= 0)
+		err = pgp_encrypt(ctx, src, dst);
+
+	/*
+	 * check for error
+	 */
+	if (err)
+	{
+		if (ex.debug)
+			px_set_debug_handler(NULL);
+		if (tmp_data)
+			clear_and_pfree(tmp_data);
+		pgp_free(ctx);
+		mbuf_free(src);
+		mbuf_free(dst);
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("%s", px_strerror(err))));
+	}
+
+	/* res_len includes VARHDRSZ */
+	res_len = mbuf_steal_data(dst, &restmp);
+	res = (bytea *) restmp;
+	SET_VARSIZE(res, res_len);
+
+	if (tmp_data)
+		clear_and_pfree(tmp_data);
+	pgp_free(ctx);
+	mbuf_free(src);
+	mbuf_free(dst);
+
+	px_set_debug_handler(NULL);
+
+	return res;
+}
+
+static bytea *
+decrypt_internal(int is_pubenc, int need_text, text *data,
+				 text *key, text *keypsw, text *args)
+{
+	int			err;
+	MBuf	   *src = NULL,
+			   *dst = NULL;
+	uint8		tmp[VARHDRSZ];
+	uint8	   *restmp;
+	bytea	   *res;
+	int			res_len;
+	PGP_Context *ctx = NULL;
+	struct debug_expect ex;
+	int			got_unicode = 0;
+
+
+	init_work(&ctx, need_text, args, &ex);
+
+	src = mbuf_create_from_data((uint8 *) VARDATA(data),
+								VARSIZE(data) - VARHDRSZ);
+	dst = mbuf_create(VARSIZE(data) + 2048);
+
+	/*
+	 * reserve room for header
+	 */
+	mbuf_append(dst, tmp, VARHDRSZ);
+
+	/*
+	 * set key
+	 */
+	if (is_pubenc)
+	{
+		uint8	   *psw = NULL;
+		int			psw_len = 0;
+		MBuf	   *kbuf;
+
+		if (keypsw)
+		{
+			psw = (uint8 *) VARDATA(keypsw);
+			psw_len = VARSIZE(keypsw) - VARHDRSZ;
+		}
+		kbuf = create_mbuf_from_vardata(key);
+		err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1);
+		mbuf_free(kbuf);
+	}
+	else
+		err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key),
+							 VARSIZE(key) - VARHDRSZ);
+
+	/*
+	 * decrypt
+	 */
+	if (err >= 0)
+		err = pgp_decrypt(ctx, src, dst);
+
+	/*
+	 * failed?
+	 */
+	if (err < 0)
+		goto out;
+
+	if (ex.expect)
+		check_expect(ctx, &ex);
+
+	/* remember the setting */
+	got_unicode = pgp_get_unicode_mode(ctx);
+
+out:
+	if (src)
+		mbuf_free(src);
+	if (ctx)
+		pgp_free(ctx);
+
+	if (err)
+	{
+		px_set_debug_handler(NULL);
+		if (dst)
+			mbuf_free(dst);
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("%s", px_strerror(err))));
+	}
+
+	res_len = mbuf_steal_data(dst, &restmp);
+	mbuf_free(dst);
+
+	/* res_len includes VARHDRSZ */
+	res = (bytea *) restmp;
+	SET_VARSIZE(res, res_len);
+
+	if (need_text && got_unicode)
+	{
+		text	   *utf = convert_from_utf8(res);
+
+		if (utf != res)
+		{
+			clear_and_pfree(res);
+			res = utf;
+		}
+	}
+	px_set_debug_handler(NULL);
+
+	/*
+	 * add successful decryptions also into RNG
+	 */
+	add_entropy(res, key, keypsw);
+
+	return res;
+}
+
+/*
+ * Wrappers for symmetric-key functions
+ */
+Datum
+pgp_sym_encrypt_bytea(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		arg = PG_GETARG_BYTEA_P(2);
+
+	res = encrypt_internal(0, 0, data, key, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(arg, 2);
+	PG_RETURN_TEXT_P(res);
+}
+
+Datum
+pgp_sym_encrypt_text(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		arg = PG_GETARG_BYTEA_P(2);
+
+	res = encrypt_internal(0, 1, data, key, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(arg, 2);
+	PG_RETURN_TEXT_P(res);
+}
+
+
+Datum
+pgp_sym_decrypt_bytea(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		arg = PG_GETARG_BYTEA_P(2);
+
+	res = decrypt_internal(0, 0, data, key, NULL, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(arg, 2);
+	PG_RETURN_TEXT_P(res);
+}
+
+Datum
+pgp_sym_decrypt_text(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		arg = PG_GETARG_BYTEA_P(2);
+
+	res = decrypt_internal(0, 1, data, key, NULL, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(arg, 2);
+	PG_RETURN_TEXT_P(res);
+}
+
+/*
+ * Wrappers for public-key functions
+ */
+
+Datum
+pgp_pub_encrypt_bytea(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		arg = PG_GETARG_BYTEA_P(2);
+
+	res = encrypt_internal(1, 0, data, key, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(arg, 2);
+	PG_RETURN_TEXT_P(res);
+}
+
+Datum
+pgp_pub_encrypt_text(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		arg = PG_GETARG_BYTEA_P(2);
+
+	res = encrypt_internal(1, 1, data, key, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(arg, 2);
+	PG_RETURN_TEXT_P(res);
+}
+
+
+Datum
+pgp_pub_decrypt_bytea(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *psw = NULL,
+			   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		psw = PG_GETARG_BYTEA_P(2);
+	if (PG_NARGS() > 3)
+		arg = PG_GETARG_BYTEA_P(3);
+
+	res = decrypt_internal(1, 0, data, key, psw, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(psw, 2);
+	if (PG_NARGS() > 3)
+		PG_FREE_IF_COPY(arg, 3);
+	PG_RETURN_TEXT_P(res);
+}
+
+Datum
+pgp_pub_decrypt_text(PG_FUNCTION_ARGS)
+{
+	bytea	   *data,
+			   *key;
+	text	   *psw = NULL,
+			   *arg = NULL;
+	text	   *res;
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	if (PG_NARGS() > 2)
+		psw = PG_GETARG_BYTEA_P(2);
+	if (PG_NARGS() > 3)
+		arg = PG_GETARG_BYTEA_P(3);
+
+	res = decrypt_internal(1, 1, data, key, psw, arg);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	if (PG_NARGS() > 2)
+		PG_FREE_IF_COPY(psw, 2);
+	if (PG_NARGS() > 3)
+		PG_FREE_IF_COPY(arg, 3);
+	PG_RETURN_TEXT_P(res);
+}
+
+
+/*
+ * Wrappers for PGP ascii armor
+ */
+
+Datum
+pg_armor(PG_FUNCTION_ARGS)
+{
+	bytea	   *data;
+	text	   *res;
+	int			data_len,
+				res_len,
+				guess_len;
+
+	data = PG_GETARG_BYTEA_P(0);
+	data_len = VARSIZE(data) - VARHDRSZ;
+
+	guess_len = pgp_armor_enc_len(data_len);
+	res = palloc(VARHDRSZ + guess_len);
+
+	res_len = pgp_armor_encode((uint8 *) VARDATA(data), data_len,
+							   (uint8 *) VARDATA(res));
+	if (res_len > guess_len)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("Overflow - encode estimate too small")));
+	SET_VARSIZE(res, VARHDRSZ + res_len);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_RETURN_TEXT_P(res);
+}
+
+Datum
+pg_dearmor(PG_FUNCTION_ARGS)
+{
+	text	   *data;
+	bytea	   *res;
+	int			data_len,
+				res_len,
+				guess_len;
+
+	data = PG_GETARG_TEXT_P(0);
+	data_len = VARSIZE(data) - VARHDRSZ;
+
+	guess_len = pgp_armor_dec_len(data_len);
+	res = palloc(VARHDRSZ + guess_len);
+
+	res_len = pgp_armor_decode((uint8 *) VARDATA(data), data_len,
+							   (uint8 *) VARDATA(res));
+	if (res_len < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("%s", px_strerror(res_len))));
+	if (res_len > guess_len)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("Overflow - decode estimate too small")));
+	SET_VARSIZE(res, VARHDRSZ + res_len);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_RETURN_TEXT_P(res);
+}
+
+/*
+ * Wrappers for PGP key id
+ */
+
+Datum
+pgp_key_id_w(PG_FUNCTION_ARGS)
+{
+	bytea	   *data;
+	text	   *res;
+	int			res_len;
+	MBuf	   *buf;
+
+	data = PG_GETARG_BYTEA_P(0);
+	buf = create_mbuf_from_vardata(data);
+	res = palloc(VARHDRSZ + 17);
+
+	res_len = pgp_get_keyid(buf, VARDATA(res));
+	mbuf_free(buf);
+	if (res_len < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("%s", px_strerror(res_len))));
+	SET_VARSIZE(res, VARHDRSZ + res_len);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_RETURN_TEXT_P(res);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-pubdec.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-pubdec.c b/contrib/pgcrypto/pgp-pubdec.c
new file mode 100644
index 0000000..fe5fae0
--- /dev/null
+++ b/contrib/pgcrypto/pgp-pubdec.c
@@ -0,0 +1,236 @@
+/*
+ * pgp-pubdec.c
+ *	  Decrypt public-key encrypted session key.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-pubdec.c
+ */
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+/*
+ * padded msg = 02 || PS || 00 || M
+ * PS - pad bytes
+ * M - msg
+ */
+static uint8 *
+check_eme_pkcs1_v15(uint8 *data, int len)
+{
+	uint8	   *data_end = data + len;
+	uint8	   *p = data;
+	int			rnd = 0;
+
+	if (len < 1 + 8 + 1)
+		return NULL;
+
+	if (*p++ != 2)
+		return NULL;
+
+	while (p < data_end && *p)
+	{
+		p++;
+		rnd++;
+	}
+
+	if (p == data_end)
+		return NULL;
+	if (*p != 0)
+		return NULL;
+	if (rnd < 8)
+		return NULL;
+	return p + 1;
+}
+
+/*
+ * secret message: 1 byte algo, sesskey, 2 byte cksum
+ * ignore algo in cksum
+ */
+static int
+control_cksum(uint8 *msg, int msglen)
+{
+	int			i;
+	unsigned	my_cksum,
+				got_cksum;
+
+	if (msglen < 3)
+		return PXE_PGP_WRONG_KEY;
+
+	my_cksum = 0;
+	for (i = 1; i < msglen - 2; i++)
+		my_cksum += msg[i];
+	my_cksum &= 0xFFFF;
+	got_cksum = ((unsigned) (msg[msglen - 2]) << 8) + msg[msglen - 1];
+	if (my_cksum != got_cksum)
+	{
+		px_debug("pubenc cksum failed");
+		return PXE_PGP_WRONG_KEY;
+	}
+	return 0;
+}
+
+static int
+decrypt_elgamal(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
+{
+	int			res;
+	PGP_MPI    *c1 = NULL;
+	PGP_MPI    *c2 = NULL;
+
+	if (pk->algo != PGP_PUB_ELG_ENCRYPT)
+		return PXE_PGP_WRONG_KEY;
+
+	/* read elgamal encrypted data */
+	res = pgp_mpi_read(pkt, &c1);
+	if (res < 0)
+		goto out;
+	res = pgp_mpi_read(pkt, &c2);
+	if (res < 0)
+		goto out;
+
+	/* decrypt */
+	res = pgp_elgamal_decrypt(pk, c1, c2, m_p);
+
+out:
+	pgp_mpi_free(c1);
+	pgp_mpi_free(c2);
+	return res;
+}
+
+static int
+decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
+{
+	int			res;
+	PGP_MPI    *c;
+
+	if (pk->algo != PGP_PUB_RSA_ENCRYPT
+		&& pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN)
+		return PXE_PGP_WRONG_KEY;
+
+	/* read rsa encrypted data */
+	res = pgp_mpi_read(pkt, &c);
+	if (res < 0)
+		return res;
+
+	/* decrypt */
+	res = pgp_rsa_decrypt(pk, c, m_p);
+
+	pgp_mpi_free(c);
+	return res;
+}
+
+/* key id is missing - user is expected to try all keys */
+static const uint8
+			any_key[] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+int
+pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
+{
+	int			ver;
+	int			algo;
+	int			res;
+	uint8		key_id[8];
+	PGP_PubKey *pk;
+	uint8	   *msg;
+	int			msglen;
+	PGP_MPI    *m;
+
+	pk = ctx->pub_key;
+	if (pk == NULL)
+	{
+		px_debug("no pubkey?");
+		return PXE_BUG;
+	}
+
+	GETBYTE(pkt, ver);
+	if (ver != 3)
+	{
+		px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
+		return PXE_PGP_CORRUPT_DATA;
+	}
+
+	/*
+	 * check if keyid's match - user-friendly msg
+	 */
+	res = pullf_read_fixed(pkt, 8, key_id);
+	if (res < 0)
+		return res;
+	if (memcmp(key_id, any_key, 8) != 0
+		&& memcmp(key_id, pk->key_id, 8) != 0)
+	{
+		px_debug("key_id's does not match");
+		return PXE_PGP_WRONG_KEY;
+	}
+
+	/*
+	 * Decrypt
+	 */
+	GETBYTE(pkt, algo);
+	switch (algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+			res = decrypt_elgamal(pk, pkt, &m);
+			break;
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			res = decrypt_rsa(pk, pkt, &m);
+			break;
+		default:
+			res = PXE_PGP_UNKNOWN_PUBALGO;
+	}
+	if (res < 0)
+		return res;
+
+	/*
+	 * extract message
+	 */
+	msg = check_eme_pkcs1_v15(m->data, m->bytes);
+	if (msg == NULL)
+	{
+		px_debug("check_eme_pkcs1_v15 failed");
+		res = PXE_PGP_WRONG_KEY;
+		goto out;
+	}
+	msglen = m->bytes - (msg - m->data);
+
+	res = control_cksum(msg, msglen);
+	if (res < 0)
+		goto out;
+
+	/*
+	 * got sesskey
+	 */
+	ctx->cipher_algo = *msg;
+	ctx->sess_key_len = msglen - 3;
+	memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len);
+
+out:
+	pgp_mpi_free(m);
+	if (res < 0)
+		return res;
+	return pgp_expect_packet_end(pkt);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-pubenc.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-pubenc.c b/contrib/pgcrypto/pgp-pubenc.c
new file mode 100644
index 0000000..943d2e4
--- /dev/null
+++ b/contrib/pgcrypto/pgp-pubenc.c
@@ -0,0 +1,250 @@
+/*
+ * pgp-pubenc.c
+ *	  Encrypt session key with public key.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-pubenc.c
+ */
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+/*
+ * padded msg: 02 || non-zero pad bytes || 00 || msg
+ */
+static int
+pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p)
+{
+	int			res;
+	uint8	   *buf,
+			   *p;
+	int			pad_len = res_len - 2 - data_len;
+
+	if (pad_len < 8)
+		return PXE_BUG;
+
+	buf = px_alloc(res_len);
+	buf[0] = 0x02;
+	res = px_get_random_bytes(buf + 1, pad_len);
+	if (res < 0)
+	{
+		px_free(buf);
+		return res;
+	}
+
+	/* pad must not contain zero bytes */
+	p = buf + 1;
+	while (p < buf + 1 + pad_len)
+	{
+		if (*p == 0)
+		{
+			res = px_get_random_bytes(p, 1);
+			if (res < 0)
+				break;
+		}
+		if (*p != 0)
+			p++;
+	}
+
+	if (res < 0)
+	{
+		memset(buf, 0, res_len);
+		px_free(buf);
+		return res;
+	}
+
+	buf[pad_len + 1] = 0;
+	memcpy(buf + pad_len + 2, data, data_len);
+	*res_p = buf;
+
+	return 0;
+}
+
+static int
+create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes)
+{
+	uint8	   *secmsg;
+	int			res,
+				i;
+	unsigned	cksum = 0;
+	int			klen = ctx->sess_key_len;
+	uint8	   *padded = NULL;
+	PGP_MPI    *m = NULL;
+
+	/* calc checksum */
+	for (i = 0; i < klen; i++)
+		cksum += ctx->sess_key[i];
+
+	/*
+	 * create "secret message"
+	 */
+	secmsg = px_alloc(klen + 3);
+	secmsg[0] = ctx->cipher_algo;
+	memcpy(secmsg + 1, ctx->sess_key, klen);
+	secmsg[klen + 1] = (cksum >> 8) & 0xFF;
+	secmsg[klen + 2] = cksum & 0xFF;
+
+	/*
+	 * now create a large integer of it
+	 */
+	res = pad_eme_pkcs1_v15(secmsg, klen + 3, full_bytes, &padded);
+	if (res >= 0)
+	{
+		/* first byte will be 0x02 */
+		int			full_bits = full_bytes * 8 - 6;
+
+		res = pgp_mpi_create(padded, full_bits, &m);
+	}
+
+	if (padded)
+	{
+		memset(padded, 0, full_bytes);
+		px_free(padded);
+	}
+	memset(secmsg, 0, klen + 3);
+	px_free(secmsg);
+
+	if (res >= 0)
+		*msg_p = m;
+
+	return res;
+}
+
+static int
+encrypt_and_write_elgamal(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
+{
+	int			res;
+	PGP_MPI    *m = NULL,
+			   *c1 = NULL,
+			   *c2 = NULL;
+
+	/* create padded msg */
+	res = create_secmsg(ctx, &m, pk->pub.elg.p->bytes - 1);
+	if (res < 0)
+		goto err;
+
+	/* encrypt it */
+	res = pgp_elgamal_encrypt(pk, m, &c1, &c2);
+	if (res < 0)
+		goto err;
+
+	/* write out */
+	res = pgp_mpi_write(pkt, c1);
+	if (res < 0)
+		goto err;
+	res = pgp_mpi_write(pkt, c2);
+
+err:
+	pgp_mpi_free(m);
+	pgp_mpi_free(c1);
+	pgp_mpi_free(c2);
+	return res;
+}
+
+static int
+encrypt_and_write_rsa(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
+{
+	int			res;
+	PGP_MPI    *m = NULL,
+			   *c = NULL;
+
+	/* create padded msg */
+	res = create_secmsg(ctx, &m, pk->pub.rsa.n->bytes - 1);
+	if (res < 0)
+		goto err;
+
+	/* encrypt it */
+	res = pgp_rsa_encrypt(pk, m, &c);
+	if (res < 0)
+		goto err;
+
+	/* write out */
+	res = pgp_mpi_write(pkt, c);
+
+err:
+	pgp_mpi_free(m);
+	pgp_mpi_free(c);
+	return res;
+}
+
+int
+pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
+{
+	int			res;
+	PGP_PubKey *pk = ctx->pub_key;
+	uint8		ver = 3;
+	PushFilter *pkt = NULL;
+	uint8		algo;
+
+	if (pk == NULL)
+	{
+		px_debug("no pubkey?\n");
+		return PXE_BUG;
+	}
+
+	algo = pk->algo;
+
+	/*
+	 * now write packet
+	 */
+	res = pgp_create_pkt_writer(dst, PGP_PKT_PUBENCRYPTED_SESSKEY, &pkt);
+	if (res < 0)
+		goto err;
+	res = pushf_write(pkt, &ver, 1);
+	if (res < 0)
+		goto err;
+	res = pushf_write(pkt, pk->key_id, 8);
+	if (res < 0)
+		goto err;
+	res = pushf_write(pkt, &algo, 1);
+	if (res < 0)
+		goto err;
+
+	switch (algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+			res = encrypt_and_write_elgamal(ctx, pk, pkt);
+			break;
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			res = encrypt_and_write_rsa(ctx, pk, pkt);
+			break;
+	}
+	if (res < 0)
+		goto err;
+
+	/*
+	 * done, signal packet end
+	 */
+	res = pushf_flush(pkt);
+err:
+	if (pkt)
+		pushf_free(pkt);
+
+	return res;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-pubkey.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-pubkey.c b/contrib/pgcrypto/pgp-pubkey.c
new file mode 100644
index 0000000..283e0ec
--- /dev/null
+++ b/contrib/pgcrypto/pgp-pubkey.c
@@ -0,0 +1,584 @@
+/*
+ * pgp-pubkey.c
+ *	  Read public or secret key.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-pubkey.c
+ */
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+int
+pgp_key_alloc(PGP_PubKey **pk_p)
+{
+	PGP_PubKey *pk;
+
+	pk = px_alloc(sizeof(*pk));
+	memset(pk, 0, sizeof(*pk));
+	*pk_p = pk;
+	return 0;
+}
+
+void
+pgp_key_free(PGP_PubKey *pk)
+{
+	if (pk == NULL)
+		return;
+
+	switch (pk->algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+			pgp_mpi_free(pk->pub.elg.p);
+			pgp_mpi_free(pk->pub.elg.g);
+			pgp_mpi_free(pk->pub.elg.y);
+			pgp_mpi_free(pk->sec.elg.x);
+			break;
+		case PGP_PUB_RSA_SIGN:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			pgp_mpi_free(pk->pub.rsa.n);
+			pgp_mpi_free(pk->pub.rsa.e);
+			pgp_mpi_free(pk->sec.rsa.d);
+			pgp_mpi_free(pk->sec.rsa.p);
+			pgp_mpi_free(pk->sec.rsa.q);
+			pgp_mpi_free(pk->sec.rsa.u);
+			break;
+		case PGP_PUB_DSA_SIGN:
+			pgp_mpi_free(pk->pub.dsa.p);
+			pgp_mpi_free(pk->pub.dsa.q);
+			pgp_mpi_free(pk->pub.dsa.g);
+			pgp_mpi_free(pk->pub.dsa.y);
+			pgp_mpi_free(pk->sec.dsa.x);
+			break;
+	}
+	memset(pk, 0, sizeof(*pk));
+	px_free(pk);
+}
+
+static int
+calc_key_id(PGP_PubKey *pk)
+{
+	int			res;
+	PX_MD	   *md;
+	int			len;
+	uint8		hdr[3];
+	uint8		hash[20];
+
+	res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
+	if (res < 0)
+		return res;
+
+	len = 1 + 4 + 1;
+	switch (pk->algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+			len += 2 + pk->pub.elg.p->bytes;
+			len += 2 + pk->pub.elg.g->bytes;
+			len += 2 + pk->pub.elg.y->bytes;
+			break;
+		case PGP_PUB_RSA_SIGN:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			len += 2 + pk->pub.rsa.n->bytes;
+			len += 2 + pk->pub.rsa.e->bytes;
+			break;
+		case PGP_PUB_DSA_SIGN:
+			len += 2 + pk->pub.dsa.p->bytes;
+			len += 2 + pk->pub.dsa.q->bytes;
+			len += 2 + pk->pub.dsa.g->bytes;
+			len += 2 + pk->pub.dsa.y->bytes;
+			break;
+	}
+
+	hdr[0] = 0x99;
+	hdr[1] = len >> 8;
+	hdr[2] = len & 0xFF;
+	px_md_update(md, hdr, 3);
+
+	px_md_update(md, &pk->ver, 1);
+	px_md_update(md, pk->time, 4);
+	px_md_update(md, &pk->algo, 1);
+
+	switch (pk->algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+			pgp_mpi_hash(md, pk->pub.elg.p);
+			pgp_mpi_hash(md, pk->pub.elg.g);
+			pgp_mpi_hash(md, pk->pub.elg.y);
+			break;
+		case PGP_PUB_RSA_SIGN:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			pgp_mpi_hash(md, pk->pub.rsa.n);
+			pgp_mpi_hash(md, pk->pub.rsa.e);
+			break;
+		case PGP_PUB_DSA_SIGN:
+			pgp_mpi_hash(md, pk->pub.dsa.p);
+			pgp_mpi_hash(md, pk->pub.dsa.q);
+			pgp_mpi_hash(md, pk->pub.dsa.g);
+			pgp_mpi_hash(md, pk->pub.dsa.y);
+			break;
+	}
+
+	px_md_finish(md, hash);
+	px_md_free(md);
+
+	memcpy(pk->key_id, hash + 12, 8);
+	memset(hash, 0, 20);
+
+	return 0;
+}
+
+int
+_pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
+{
+	int			res;
+	PGP_PubKey *pk;
+
+	res = pgp_key_alloc(&pk);
+	if (res < 0)
+		return res;
+
+	/* get version */
+	GETBYTE(pkt, pk->ver);
+	if (pk->ver != 4)
+	{
+		res = PXE_PGP_NOT_V4_KEYPKT;
+		goto out;
+	}
+
+	/* read time */
+	res = pullf_read_fixed(pkt, 4, pk->time);
+	if (res < 0)
+		goto out;
+
+	/* pubkey algorithm */
+	GETBYTE(pkt, pk->algo);
+
+	switch (pk->algo)
+	{
+		case PGP_PUB_DSA_SIGN:
+			res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
+			if (res < 0)
+				break;
+
+			res = calc_key_id(pk);
+			break;
+
+		case PGP_PUB_RSA_SIGN:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
+			if (res < 0)
+				break;
+
+			res = calc_key_id(pk);
+
+			if (pk->algo != PGP_PUB_RSA_SIGN)
+				pk->can_encrypt = 1;
+			break;
+
+		case PGP_PUB_ELG_ENCRYPT:
+			res = pgp_mpi_read(pkt, &pk->pub.elg.p);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->pub.elg.g);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->pub.elg.y);
+			if (res < 0)
+				break;
+
+			res = calc_key_id(pk);
+
+			pk->can_encrypt = 1;
+			break;
+
+		default:
+			px_debug("unknown public algo: %d", pk->algo);
+			res = PXE_PGP_UNKNOWN_PUBALGO;
+	}
+
+out:
+	if (res < 0)
+		pgp_key_free(pk);
+	else
+		*pk_p = pk;
+
+	return res;
+}
+
+#define HIDE_CLEAR 0
+#define HIDE_CKSUM 255
+#define HIDE_SHA1 254
+
+static int
+check_key_sha1(PullFilter *src, PGP_PubKey *pk)
+{
+	int			res;
+	uint8		got_sha1[20];
+	uint8		my_sha1[20];
+	PX_MD	   *md;
+
+	res = pullf_read_fixed(src, 20, got_sha1);
+	if (res < 0)
+		return res;
+
+	res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
+	if (res < 0)
+		goto err;
+	switch (pk->algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+			pgp_mpi_hash(md, pk->sec.elg.x);
+			break;
+		case PGP_PUB_RSA_SIGN:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			pgp_mpi_hash(md, pk->sec.rsa.d);
+			pgp_mpi_hash(md, pk->sec.rsa.p);
+			pgp_mpi_hash(md, pk->sec.rsa.q);
+			pgp_mpi_hash(md, pk->sec.rsa.u);
+			break;
+		case PGP_PUB_DSA_SIGN:
+			pgp_mpi_hash(md, pk->sec.dsa.x);
+			break;
+	}
+	px_md_finish(md, my_sha1);
+	px_md_free(md);
+
+	if (memcmp(my_sha1, got_sha1, 20) != 0)
+	{
+		px_debug("key sha1 check failed");
+		res = PXE_PGP_KEYPKT_CORRUPT;
+	}
+err:
+	memset(got_sha1, 0, 20);
+	memset(my_sha1, 0, 20);
+	return res;
+}
+
+static int
+check_key_cksum(PullFilter *src, PGP_PubKey *pk)
+{
+	int			res;
+	unsigned	got_cksum,
+				my_cksum = 0;
+	uint8		buf[2];
+
+	res = pullf_read_fixed(src, 2, buf);
+	if (res < 0)
+		return res;
+
+	got_cksum = ((unsigned) buf[0] << 8) + buf[1];
+	switch (pk->algo)
+	{
+		case PGP_PUB_ELG_ENCRYPT:
+			my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
+			break;
+		case PGP_PUB_RSA_SIGN:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
+			my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
+			my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
+			my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
+			break;
+		case PGP_PUB_DSA_SIGN:
+			my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
+			break;
+	}
+	if (my_cksum != got_cksum)
+	{
+		px_debug("key cksum check failed");
+		return PXE_PGP_KEYPKT_CORRUPT;
+	}
+	return 0;
+}
+
+static int
+process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
+				   const uint8 *key, int key_len)
+{
+	int			res;
+	int			hide_type;
+	int			cipher_algo;
+	int			bs;
+	uint8		iv[512];
+	PullFilter *pf_decrypt = NULL,
+			   *pf_key;
+	PGP_CFB    *cfb = NULL;
+	PGP_S2K		s2k;
+	PGP_PubKey *pk;
+
+	/* first read public key part */
+	res = _pgp_read_public_key(pkt, &pk);
+	if (res < 0)
+		return res;
+
+	/*
+	 * is secret key encrypted?
+	 */
+	GETBYTE(pkt, hide_type);
+	if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM)
+	{
+		if (key == NULL)
+			return PXE_PGP_NEED_SECRET_PSW;
+		GETBYTE(pkt, cipher_algo);
+		res = pgp_s2k_read(pkt, &s2k);
+		if (res < 0)
+			return res;
+
+		res = pgp_s2k_process(&s2k, cipher_algo, key, key_len);
+		if (res < 0)
+			return res;
+
+		bs = pgp_get_cipher_block_size(cipher_algo);
+		if (bs == 0)
+		{
+			px_debug("unknown cipher algo=%d", cipher_algo);
+			return PXE_PGP_UNSUPPORTED_CIPHER;
+		}
+		res = pullf_read_fixed(pkt, bs, iv);
+		if (res < 0)
+			return res;
+
+		/*
+		 * create decrypt filter
+		 */
+		res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv);
+		if (res < 0)
+			return res;
+		res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
+		if (res < 0)
+			return res;
+		pf_key = pf_decrypt;
+	}
+	else if (hide_type == HIDE_CLEAR)
+	{
+		pf_key = pkt;
+	}
+	else
+	{
+		px_debug("unknown hide type");
+		return PXE_PGP_KEYPKT_CORRUPT;
+	}
+
+	/* read secret key */
+	switch (pk->algo)
+	{
+		case PGP_PUB_RSA_SIGN:
+		case PGP_PUB_RSA_ENCRYPT:
+		case PGP_PUB_RSA_ENCRYPT_SIGN:
+			res = pgp_mpi_read(pkt, &pk->sec.rsa.d);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->sec.rsa.p);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->sec.rsa.q);
+			if (res < 0)
+				break;
+			res = pgp_mpi_read(pkt, &pk->sec.rsa.u);
+			if (res < 0)
+				break;
+			break;
+		case PGP_PUB_ELG_ENCRYPT:
+			res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
+			break;
+		case PGP_PUB_DSA_SIGN:
+			res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
+			break;
+		default:
+			px_debug("unknown public algo: %d", pk->algo);
+			res = PXE_PGP_KEYPKT_CORRUPT;
+	}
+	/* read checksum / sha1 */
+	if (res >= 0)
+	{
+		if (hide_type == HIDE_SHA1)
+			res = check_key_sha1(pf_key, pk);
+		else
+			res = check_key_cksum(pf_key, pk);
+	}
+	if (res >= 0)
+		res = pgp_expect_packet_end(pf_key);
+
+	if (pf_decrypt)
+		pullf_free(pf_decrypt);
+	if (cfb)
+		pgp_cfb_free(cfb);
+
+	if (res < 0)
+		pgp_key_free(pk);
+	else
+		*pk_p = pk;
+
+	return res;
+}
+
+static int
+internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
+				  const uint8 *psw, int psw_len, int pubtype)
+{
+	PullFilter *pkt = NULL;
+	int			res;
+	uint8		tag;
+	int			len;
+	PGP_PubKey *enc_key = NULL;
+	PGP_PubKey *pk = NULL;
+	int			got_main_key = 0;
+
+	/*
+	 * Search for encryption key.
+	 *
+	 * Error out on anything fancy.
+	 */
+	while (1)
+	{
+		res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
+		if (res <= 0)
+			break;
+		res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
+		if (res < 0)
+			break;
+
+		switch (tag)
+		{
+			case PGP_PKT_PUBLIC_KEY:
+			case PGP_PKT_SECRET_KEY:
+				if (got_main_key)
+				{
+					res = PXE_PGP_MULTIPLE_KEYS;
+					break;
+				}
+				got_main_key = 1;
+				res = pgp_skip_packet(pkt);
+				break;
+
+			case PGP_PKT_PUBLIC_SUBKEY:
+				if (pubtype != 0)
+					res = PXE_PGP_EXPECT_SECRET_KEY;
+				else
+					res = _pgp_read_public_key(pkt, &pk);
+				break;
+
+			case PGP_PKT_SECRET_SUBKEY:
+				if (pubtype != 1)
+					res = PXE_PGP_EXPECT_PUBLIC_KEY;
+				else
+					res = process_secret_key(pkt, &pk, psw, psw_len);
+				break;
+
+			case PGP_PKT_SIGNATURE:
+			case PGP_PKT_MARKER:
+			case PGP_PKT_TRUST:
+			case PGP_PKT_USER_ID:
+			case PGP_PKT_USER_ATTR:
+			case PGP_PKT_PRIV_61:
+				res = pgp_skip_packet(pkt);
+				break;
+			default:
+				px_debug("unknown/unexpected packet: %d", tag);
+				res = PXE_PGP_UNEXPECTED_PKT;
+		}
+		pullf_free(pkt);
+		pkt = NULL;
+
+		if (pk != NULL)
+		{
+			if (res >= 0 && pk->can_encrypt)
+			{
+				if (enc_key == NULL)
+				{
+					enc_key = pk;
+					pk = NULL;
+				}
+				else
+					res = PXE_PGP_MULTIPLE_SUBKEYS;
+			}
+
+			if (pk)
+				pgp_key_free(pk);
+			pk = NULL;
+		}
+
+		if (res < 0)
+			break;
+	}
+
+	if (pkt)
+		pullf_free(pkt);
+
+	if (res < 0)
+	{
+		if (enc_key)
+			pgp_key_free(enc_key);
+		return res;
+	}
+
+	if (!enc_key)
+		res = PXE_PGP_NO_USABLE_KEY;
+	else
+		*pk_p = enc_key;
+	return res;
+}
+
+int
+pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
+			   const uint8 *key, int key_len, int pubtype)
+{
+	int			res;
+	PullFilter *src;
+	PGP_PubKey *pk = NULL;
+
+	res = pullf_create_mbuf_reader(&src, keypkt);
+	if (res < 0)
+		return res;
+
+	res = internal_read_key(src, &pk, key, key_len, pubtype);
+	pullf_free(src);
+
+	if (res >= 0)
+		ctx->pub_key = pk;
+
+	return res < 0 ? res : 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp-s2k.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c
new file mode 100644
index 0000000..349234e
--- /dev/null
+++ b/contrib/pgcrypto/pgp-s2k.c
@@ -0,0 +1,296 @@
+/*
+ * pgp-s2k.c
+ *	  OpenPGP string2key functions.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp-s2k.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+static int
+calc_s2k_simple(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
+				unsigned key_len)
+{
+	unsigned	md_rlen;
+	uint8		buf[PGP_MAX_DIGEST];
+	unsigned	preload;
+	unsigned	remain;
+	uint8	   *dst = s2k->key;
+
+	md_rlen = px_md_result_size(md);
+
+	remain = s2k->key_len;
+	preload = 0;
+	while (remain > 0)
+	{
+		px_md_reset(md);
+
+		if (preload)
+		{
+			memset(buf, 0, preload);
+			px_md_update(md, buf, preload);
+		}
+		preload++;
+
+		px_md_update(md, key, key_len);
+		px_md_finish(md, buf);
+
+		if (remain > md_rlen)
+		{
+			memcpy(dst, buf, md_rlen);
+			dst += md_rlen;
+			remain -= md_rlen;
+		}
+		else
+		{
+			memcpy(dst, buf, remain);
+			remain = 0;
+		}
+	}
+	return 0;
+}
+
+static int
+calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len)
+{
+	unsigned	md_rlen;
+	uint8		buf[PGP_MAX_DIGEST];
+	unsigned	preload = 0;
+	uint8	   *dst;
+	unsigned	remain;
+
+	md_rlen = px_md_result_size(md);
+
+	dst = s2k->key;
+	remain = s2k->key_len;
+	while (remain > 0)
+	{
+		px_md_reset(md);
+
+		if (preload > 0)
+		{
+			memset(buf, 0, preload);
+			px_md_update(md, buf, preload);
+		}
+		preload++;
+
+		px_md_update(md, s2k->salt, PGP_S2K_SALT);
+		px_md_update(md, key, key_len);
+		px_md_finish(md, buf);
+
+		if (remain > md_rlen)
+		{
+			memcpy(dst, buf, md_rlen);
+			remain -= md_rlen;
+			dst += md_rlen;
+		}
+		else
+		{
+			memcpy(dst, buf, remain);
+			remain = 0;
+		}
+	}
+	return 0;
+}
+
+static int
+calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key,
+					 unsigned key_len)
+{
+	unsigned	md_rlen;
+	uint8		buf[PGP_MAX_DIGEST];
+	uint8	   *dst;
+	unsigned	preload = 0;
+	unsigned	remain,
+				c,
+				cval,
+				curcnt,
+				count;
+
+	cval = s2k->iter;
+	count = ((unsigned) 16 + (cval & 15)) << ((cval >> 4) + 6);
+
+	md_rlen = px_md_result_size(md);
+
+	remain = s2k->key_len;
+	dst = s2k->key;
+	while (remain > 0)
+	{
+		px_md_reset(md);
+
+		if (preload)
+		{
+			memset(buf, 0, preload);
+			px_md_update(md, buf, preload);
+		}
+		preload++;
+
+		px_md_update(md, s2k->salt, PGP_S2K_SALT);
+		px_md_update(md, key, key_len);
+		curcnt = PGP_S2K_SALT + key_len;
+
+		while (curcnt < count)
+		{
+			if (curcnt + PGP_S2K_SALT < count)
+				c = PGP_S2K_SALT;
+			else
+				c = count - curcnt;
+			px_md_update(md, s2k->salt, c);
+			curcnt += c;
+
+			if (curcnt + key_len < count)
+				c = key_len;
+			else if (curcnt < count)
+				c = count - curcnt;
+			else
+				break;
+			px_md_update(md, key, c);
+			curcnt += c;
+		}
+		px_md_finish(md, buf);
+
+		if (remain > md_rlen)
+		{
+			memcpy(dst, buf, md_rlen);
+			remain -= md_rlen;
+			dst += md_rlen;
+		}
+		else
+		{
+			memcpy(dst, buf, remain);
+			remain = 0;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Decide S2K_ISALTED iteration count
+ *
+ * Too small: weak
+ * Too big: slow
+ * gpg defaults to 96 => 65536 iters
+ * let it float a bit: 96 + 32 => 262144 iters
+ */
+static int
+decide_count(unsigned rand_byte)
+{
+	return 96 + (rand_byte & 0x1F);
+}
+
+int
+pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo)
+{
+	int			res = 0;
+	uint8		tmp;
+
+	s2k->mode = mode;
+	s2k->digest_algo = digest_algo;
+
+	switch (s2k->mode)
+	{
+		case 0:
+			break;
+		case 1:
+			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			break;
+		case 3:
+			res = px_get_pseudo_random_bytes(s2k->salt, PGP_S2K_SALT);
+			if (res < 0)
+				break;
+			res = px_get_pseudo_random_bytes(&tmp, 1);
+			if (res < 0)
+				break;
+			s2k->iter = decide_count(tmp);
+			break;
+		default:
+			res = PXE_PGP_BAD_S2K_MODE;
+	}
+	return res;
+}
+
+int
+pgp_s2k_read(PullFilter *src, PGP_S2K *s2k)
+{
+	int			res = 0;
+
+	GETBYTE(src, s2k->mode);
+	GETBYTE(src, s2k->digest_algo);
+	switch (s2k->mode)
+	{
+		case 0:
+			break;
+		case 1:
+			res = pullf_read_fixed(src, 8, s2k->salt);
+			break;
+		case 3:
+			res = pullf_read_fixed(src, 8, s2k->salt);
+			if (res < 0)
+				break;
+			GETBYTE(src, s2k->iter);
+			break;
+		default:
+			res = PXE_PGP_BAD_S2K_MODE;
+	}
+	return res;
+}
+
+int
+pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len)
+{
+	int			res;
+	PX_MD	   *md;
+
+	s2k->key_len = pgp_get_cipher_key_size(cipher);
+	if (s2k->key_len <= 0)
+		return PXE_PGP_UNSUPPORTED_CIPHER;
+
+	res = pgp_load_digest(s2k->digest_algo, &md);
+	if (res < 0)
+		return res;
+
+	switch (s2k->mode)
+	{
+		case 0:
+			res = calc_s2k_simple(s2k, md, key, key_len);
+			break;
+		case 1:
+			res = calc_s2k_salted(s2k, md, key, key_len);
+			break;
+		case 3:
+			res = calc_s2k_iter_salted(s2k, md, key, key_len);
+			break;
+		default:
+			res = PXE_PGP_BAD_S2K_MODE;
+	}
+	px_md_free(md);
+	return res;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp.c b/contrib/pgcrypto/pgp.c
new file mode 100644
index 0000000..b8a6bc4
--- /dev/null
+++ b/contrib/pgcrypto/pgp.c
@@ -0,0 +1,360 @@
+/*
+ * pgp.c
+ *	  Various utility stuff.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+#include "pgp.h"
+
+/*
+ * Defaults.
+ */
+static int	def_cipher_algo = PGP_SYM_AES_128;
+static int	def_s2k_cipher_algo = -1;
+static int	def_s2k_mode = PGP_S2K_ISALTED;
+static int	def_s2k_digest_algo = PGP_DIGEST_SHA1;
+static int	def_compress_algo = PGP_COMPR_NONE;
+static int	def_compress_level = 6;
+static int	def_disable_mdc = 0;
+static int	def_use_sess_key = 0;
+static int	def_text_mode = 0;
+static int	def_unicode_mode = 0;
+static int	def_convert_crlf = 0;
+
+struct digest_info
+{
+	const char *name;
+	int			code;
+	const char *int_name;
+};
+
+struct cipher_info
+{
+	const char *name;
+	int			code;
+	const char *int_name;
+	int			key_len;
+	int			block_len;
+};
+
+static const struct digest_info digest_list[] = {
+	{"md5", PGP_DIGEST_MD5},
+	{"sha1", PGP_DIGEST_SHA1},
+	{"sha-1", PGP_DIGEST_SHA1},
+	{"ripemd160", PGP_DIGEST_RIPEMD160},
+	{"sha256", PGP_DIGEST_SHA256},
+	{"sha384", PGP_DIGEST_SHA384},
+	{"sha512", PGP_DIGEST_SHA512},
+	{NULL, 0}
+};
+
+static const struct cipher_info cipher_list[] = {
+	{"3des", PGP_SYM_DES3, "3des-ecb", 192 / 8, 64 / 8},
+	{"cast5", PGP_SYM_CAST5, "cast5-ecb", 128 / 8, 64 / 8},
+	{"bf", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
+	{"blowfish", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
+	{"aes", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
+	{"aes128", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
+	{"aes192", PGP_SYM_AES_192, "aes-ecb", 192 / 8, 128 / 8},
+	{"aes256", PGP_SYM_AES_256, "aes-ecb", 256 / 8, 128 / 8},
+	{"twofish", PGP_SYM_TWOFISH, "twofish-ecb", 256 / 8, 128 / 8},
+	{NULL, 0, NULL}
+};
+
+static const struct cipher_info *
+get_cipher_info(int code)
+{
+	const struct cipher_info *i;
+
+	for (i = cipher_list; i->name; i++)
+		if (i->code == code)
+			return i;
+	return NULL;
+}
+
+int
+pgp_get_digest_code(const char *name)
+{
+	const struct digest_info *i;
+
+	for (i = digest_list; i->name; i++)
+		if (pg_strcasecmp(i->name, name) == 0)
+			return i->code;
+	return PXE_PGP_UNSUPPORTED_HASH;
+}
+
+int
+pgp_get_cipher_code(const char *name)
+{
+	const struct cipher_info *i;
+
+	for (i = cipher_list; i->name; i++)
+		if (pg_strcasecmp(i->name, name) == 0)
+			return i->code;
+	return PXE_PGP_UNSUPPORTED_CIPHER;
+}
+
+const char *
+pgp_get_digest_name(int code)
+{
+	const struct digest_info *i;
+
+	for (i = digest_list; i->name; i++)
+		if (i->code == code)
+			return i->name;
+	return NULL;
+}
+
+const char *
+pgp_get_cipher_name(int code)
+{
+	const struct cipher_info *i = get_cipher_info(code);
+
+	if (i != NULL)
+		return i->name;
+	return NULL;
+}
+
+int
+pgp_get_cipher_key_size(int code)
+{
+	const struct cipher_info *i = get_cipher_info(code);
+
+	if (i != NULL)
+		return i->key_len;
+	return 0;
+}
+
+int
+pgp_get_cipher_block_size(int code)
+{
+	const struct cipher_info *i = get_cipher_info(code);
+
+	if (i != NULL)
+		return i->block_len;
+	return 0;
+}
+
+int
+pgp_load_cipher(int code, PX_Cipher **res)
+{
+	int			err;
+	const struct cipher_info *i = get_cipher_info(code);
+
+	if (i == NULL)
+		return PXE_PGP_CORRUPT_DATA;
+
+	err = px_find_cipher(i->int_name, res);
+	if (err == 0)
+		return 0;
+
+	return PXE_PGP_UNSUPPORTED_CIPHER;
+}
+
+int
+pgp_load_digest(int code, PX_MD **res)
+{
+	int			err;
+	const char *name = pgp_get_digest_name(code);
+
+	if (name == NULL)
+		return PXE_PGP_CORRUPT_DATA;
+
+	err = px_find_digest(name, res);
+	if (err == 0)
+		return 0;
+
+	return PXE_PGP_UNSUPPORTED_HASH;
+}
+
+int
+pgp_init(PGP_Context **ctx_p)
+{
+	PGP_Context *ctx;
+
+	ctx = px_alloc(sizeof *ctx);
+	memset(ctx, 0, sizeof *ctx);
+
+	ctx->cipher_algo = def_cipher_algo;
+	ctx->s2k_cipher_algo = def_s2k_cipher_algo;
+	ctx->s2k_mode = def_s2k_mode;
+	ctx->s2k_digest_algo = def_s2k_digest_algo;
+	ctx->compress_algo = def_compress_algo;
+	ctx->compress_level = def_compress_level;
+	ctx->disable_mdc = def_disable_mdc;
+	ctx->use_sess_key = def_use_sess_key;
+	ctx->unicode_mode = def_unicode_mode;
+	ctx->convert_crlf = def_convert_crlf;
+	ctx->text_mode = def_text_mode;
+
+	*ctx_p = ctx;
+	return 0;
+}
+
+int
+pgp_free(PGP_Context *ctx)
+{
+	if (ctx->pub_key)
+		pgp_key_free(ctx->pub_key);
+	memset(ctx, 0, sizeof *ctx);
+	px_free(ctx);
+	return 0;
+}
+
+int
+pgp_disable_mdc(PGP_Context *ctx, int disable)
+{
+	ctx->disable_mdc = disable ? 1 : 0;
+	return 0;
+}
+
+int
+pgp_set_sess_key(PGP_Context *ctx, int use)
+{
+	ctx->use_sess_key = use ? 1 : 0;
+	return 0;
+}
+
+int
+pgp_set_convert_crlf(PGP_Context *ctx, int doit)
+{
+	ctx->convert_crlf = doit ? 1 : 0;
+	return 0;
+}
+
+int
+pgp_set_s2k_mode(PGP_Context *ctx, int mode)
+{
+	int			err = PXE_OK;
+
+	switch (mode)
+	{
+		case PGP_S2K_SIMPLE:
+		case PGP_S2K_SALTED:
+		case PGP_S2K_ISALTED:
+			ctx->s2k_mode = mode;
+			break;
+		default:
+			err = PXE_ARGUMENT_ERROR;
+			break;
+	}
+	return err;
+}
+
+int
+pgp_set_compress_algo(PGP_Context *ctx, int algo)
+{
+	switch (algo)
+	{
+		case PGP_COMPR_NONE:
+		case PGP_COMPR_ZIP:
+		case PGP_COMPR_ZLIB:
+		case PGP_COMPR_BZIP2:
+			ctx->compress_algo = algo;
+			return 0;
+	}
+	return PXE_ARGUMENT_ERROR;
+}
+
+int
+pgp_set_compress_level(PGP_Context *ctx, int level)
+{
+	if (level >= 0 && level <= 9)
+	{
+		ctx->compress_level = level;
+		return 0;
+	}
+	return PXE_ARGUMENT_ERROR;
+}
+
+int
+pgp_set_text_mode(PGP_Context *ctx, int mode)
+{
+	ctx->text_mode = mode;
+	return 0;
+}
+
+int
+pgp_set_cipher_algo(PGP_Context *ctx, const char *name)
+{
+	int			code = pgp_get_cipher_code(name);
+
+	if (code < 0)
+		return code;
+	ctx->cipher_algo = code;
+	return 0;
+}
+
+int
+pgp_set_s2k_cipher_algo(PGP_Context *ctx, const char *name)
+{
+	int			code = pgp_get_cipher_code(name);
+
+	if (code < 0)
+		return code;
+	ctx->s2k_cipher_algo = code;
+	return 0;
+}
+
+int
+pgp_set_s2k_digest_algo(PGP_Context *ctx, const char *name)
+{
+	int			code = pgp_get_digest_code(name);
+
+	if (code < 0)
+		return code;
+	ctx->s2k_digest_algo = code;
+	return 0;
+}
+
+int
+pgp_get_unicode_mode(PGP_Context *ctx)
+{
+	return ctx->unicode_mode;
+}
+
+int
+pgp_set_unicode_mode(PGP_Context *ctx, int mode)
+{
+	ctx->unicode_mode = mode ? 1 : 0;
+	return 0;
+}
+
+int
+pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
+{
+	if (key == NULL || len < 1)
+		return PXE_ARGUMENT_ERROR;
+	ctx->sym_key = key;
+	ctx->sym_key_len = len;
+	return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgp.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgp.h b/contrib/pgcrypto/pgp.h
new file mode 100644
index 0000000..7ae01cc
--- /dev/null
+++ b/contrib/pgcrypto/pgp.h
@@ -0,0 +1,314 @@
+/*
+ * pgp.h
+ *	  OpenPGP implementation.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgp.h
+ */
+
+enum PGP_S2K_TYPE
+{
+	PGP_S2K_SIMPLE = 0,
+	PGP_S2K_SALTED = 1,
+	PGP_S2K_ISALTED = 3
+};
+
+enum PGP_PKT_TYPE
+{
+	PGP_PKT_RESERVED = 0,
+	PGP_PKT_PUBENCRYPTED_SESSKEY = 1,
+	PGP_PKT_SIGNATURE = 2,
+	PGP_PKT_SYMENCRYPTED_SESSKEY = 3,
+	PGP_PKT_SECRET_KEY = 5,
+	PGP_PKT_PUBLIC_KEY = 6,
+	PGP_PKT_SECRET_SUBKEY = 7,
+	PGP_PKT_COMPRESSED_DATA = 8,
+	PGP_PKT_SYMENCRYPTED_DATA = 9,
+	PGP_PKT_MARKER = 10,
+	PGP_PKT_LITERAL_DATA = 11,
+	PGP_PKT_TRUST = 12,
+	PGP_PKT_USER_ID = 13,
+	PGP_PKT_PUBLIC_SUBKEY = 14,
+	PGP_PKT_USER_ATTR = 17,
+	PGP_PKT_SYMENCRYPTED_DATA_MDC = 18,
+	PGP_PKT_MDC = 19,
+	PGP_PKT_PRIV_61 = 61		/* occurs in gpg secring */
+};
+
+enum PGP_PUB_ALGO_TYPE
+{
+	PGP_PUB_RSA_ENCRYPT_SIGN = 1,
+	PGP_PUB_RSA_ENCRYPT = 2,
+	PGP_PUB_RSA_SIGN = 3,
+	PGP_PUB_ELG_ENCRYPT = 16,
+	PGP_PUB_DSA_SIGN = 17
+};
+
+enum PGP_SYMENC_TYPE
+{
+	PGP_SYM_PLAIN = 0,			/* ?? */
+	PGP_SYM_IDEA = 1,			/* obsolete, PGP 2.6 compat */
+	PGP_SYM_DES3 = 2,			/* must */
+	PGP_SYM_CAST5 = 3,			/* should */
+	PGP_SYM_BLOWFISH = 4,
+	PGP_SYM_SAFER_SK128 = 5,	/* obsolete */
+	PGP_SYM_DES_SK = 6,			/* obsolete */
+	PGP_SYM_AES_128 = 7,		/* should */
+	PGP_SYM_AES_192 = 8,
+	PGP_SYM_AES_256 = 9,
+	PGP_SYM_TWOFISH = 10
+};
+
+enum PGP_COMPR_TYPE
+{
+	PGP_COMPR_NONE = 0,			/* must */
+	PGP_COMPR_ZIP = 1,			/* should */
+	PGP_COMPR_ZLIB = 2,
+	PGP_COMPR_BZIP2 = 3
+};
+
+enum PGP_DIGEST_TYPE
+{
+	PGP_DIGEST_MD5 = 1,			/* should, deprecated  */
+	PGP_DIGEST_SHA1 = 2,		/* must */
+	PGP_DIGEST_RIPEMD160 = 3,
+	PGP_DIGEST_XSHA = 4,		/* obsolete */
+	PGP_DIGEST_MD2 = 5,			/* obsolete */
+	PGP_DIGEST_TIGER192 = 6,	/* obsolete */
+	PGP_DIGEST_HAVAL5_160 = 7,	/* obsolete */
+	PGP_DIGEST_SHA256 = 8,
+	PGP_DIGEST_SHA384 = 9,
+	PGP_DIGEST_SHA512 = 10
+};
+
+#define PGP_MAX_KEY    (256/8)
+#define PGP_MAX_BLOCK  (256/8)
+#define PGP_MAX_DIGEST (512/8)
+#define PGP_S2K_SALT   8
+
+typedef struct PGP_MPI PGP_MPI;
+typedef struct PGP_PubKey PGP_PubKey;
+typedef struct PGP_Context PGP_Context;
+typedef struct PGP_S2K PGP_S2K;
+
+struct PGP_S2K
+{
+	uint8		mode;
+	uint8		digest_algo;
+	uint8		salt[8];
+	uint8		iter;
+	/* calculated: */
+	uint8		key[PGP_MAX_KEY];
+	uint8		key_len;
+};
+
+
+struct PGP_Context
+{
+	/*
+	 * parameters
+	 */
+	PGP_S2K		s2k;
+	int			s2k_mode;
+	int			s2k_digest_algo;
+	int			s2k_cipher_algo;
+	int			cipher_algo;
+	int			compress_algo;
+	int			compress_level;
+	int			disable_mdc;
+	int			use_sess_key;
+	int			text_mode;
+	int			convert_crlf;
+	int			unicode_mode;
+
+	/*
+	 * internal variables
+	 */
+	int			mdc_checked;
+	int			corrupt_prefix;
+	int			in_mdc_pkt;
+	int			use_mdcbuf_filter;
+	PX_MD	   *mdc_ctx;
+
+	PGP_PubKey *pub_key;		/* ctx owns it */
+	const uint8 *sym_key;		/* ctx does not own it */
+	int			sym_key_len;
+
+	/*
+	 * read or generated data
+	 */
+	uint8		sess_key[PGP_MAX_KEY];
+	unsigned	sess_key_len;
+};
+
+struct PGP_MPI
+{
+	uint8	   *data;
+	int			bits;
+	int			bytes;
+};
+
+struct PGP_PubKey
+{
+	uint8		ver;
+	uint8		time[4];
+	uint8		algo;
+
+	/* public part */
+	union
+	{
+		struct
+		{
+			PGP_MPI    *p;
+			PGP_MPI    *g;
+			PGP_MPI    *y;
+		}			elg;
+		struct
+		{
+			PGP_MPI    *n;
+			PGP_MPI    *e;
+		}			rsa;
+		struct
+		{
+			PGP_MPI    *p;
+			PGP_MPI    *q;
+			PGP_MPI    *g;
+			PGP_MPI    *y;
+		}			dsa;
+	}			pub;
+
+	/* secret part */
+	union
+	{
+		struct
+		{
+			PGP_MPI    *x;
+		}			elg;
+		struct
+		{
+			PGP_MPI    *d;
+			PGP_MPI    *p;
+			PGP_MPI    *q;
+			PGP_MPI    *u;
+		}			rsa;
+		struct
+		{
+			PGP_MPI    *x;
+		}			dsa;
+	}			sec;
+
+	uint8		key_id[8];
+	int			can_encrypt;
+};
+
+int			pgp_init(PGP_Context **ctx);
+int			pgp_encrypt(PGP_Context *ctx, MBuf *src, MBuf *dst);
+int			pgp_decrypt(PGP_Context *ctx, MBuf *src, MBuf *dst);
+int			pgp_free(PGP_Context *ctx);
+
+int			pgp_get_digest_code(const char *name);
+int			pgp_get_cipher_code(const char *name);
+const char *pgp_get_digest_name(int code);
+const char *pgp_get_cipher_name(int code);
+
+int			pgp_set_cipher_algo(PGP_Context *ctx, const char *name);
+int			pgp_set_s2k_mode(PGP_Context *ctx, int type);
+int			pgp_set_s2k_cipher_algo(PGP_Context *ctx, const char *name);
+int			pgp_set_s2k_digest_algo(PGP_Context *ctx, const char *name);
+int			pgp_set_convert_crlf(PGP_Context *ctx, int doit);
+int			pgp_disable_mdc(PGP_Context *ctx, int disable);
+int			pgp_set_sess_key(PGP_Context *ctx, int use);
+int			pgp_set_compress_algo(PGP_Context *ctx, int algo);
+int			pgp_set_compress_level(PGP_Context *ctx, int level);
+int			pgp_set_text_mode(PGP_Context *ctx, int mode);
+int			pgp_set_unicode_mode(PGP_Context *ctx, int mode);
+int			pgp_get_unicode_mode(PGP_Context *ctx);
+
+int			pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int klen);
+int pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
+			   const uint8 *key, int klen, int pubtype);
+
+int			pgp_get_keyid(MBuf *pgp_data, char *dst);
+
+/* internal functions */
+
+int			pgp_load_digest(int c, PX_MD **res);
+int			pgp_load_cipher(int c, PX_Cipher **res);
+int			pgp_get_cipher_key_size(int c);
+int			pgp_get_cipher_block_size(int c);
+
+int			pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo);
+int			pgp_s2k_read(PullFilter *src, PGP_S2K *s2k);
+int			pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int klen);
+
+typedef struct PGP_CFB PGP_CFB;
+int
+pgp_cfb_create(PGP_CFB **ctx_p, int algo,
+			   const uint8 *key, int key_len, int recync, uint8 *iv);
+void		pgp_cfb_free(PGP_CFB *ctx);
+int			pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
+int			pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst);
+
+int			pgp_armor_encode(const uint8 *src, unsigned len, uint8 *dst);
+int			pgp_armor_decode(const uint8 *src, unsigned len, uint8 *dst);
+unsigned	pgp_armor_enc_len(unsigned len);
+unsigned	pgp_armor_dec_len(unsigned len);
+
+int			pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst);
+int			pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src);
+
+int			pgp_key_alloc(PGP_PubKey **pk_p);
+void		pgp_key_free(PGP_PubKey *pk);
+int			_pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p);
+
+int			pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt);
+int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
+					  int pkttype, PGP_Context *ctx);
+int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p,
+				  int allow_ctx);
+
+int			pgp_skip_packet(PullFilter *pkt);
+int			pgp_expect_packet_end(PullFilter *pkt);
+
+int			pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst);
+int			pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p);
+
+int			pgp_mpi_alloc(int bits, PGP_MPI **mpi);
+int			pgp_mpi_create(uint8 *data, int bits, PGP_MPI **mpi);
+int			pgp_mpi_free(PGP_MPI *mpi);
+int			pgp_mpi_read(PullFilter *src, PGP_MPI **mpi);
+int			pgp_mpi_write(PushFilter *dst, PGP_MPI *n);
+int			pgp_mpi_hash(PX_MD *md, PGP_MPI *n);
+unsigned	pgp_mpi_cksum(unsigned cksum, PGP_MPI *n);
+
+int pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *m,
+					PGP_MPI **c1, PGP_MPI **c2);
+int pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *c1, PGP_MPI *c2,
+					PGP_MPI **m);
+int			pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c);
+int			pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m);
+
+extern struct PullFilterOps pgp_decrypt_filter;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/px-crypt.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c
new file mode 100644
index 0000000..63ec038
--- /dev/null
+++ b/contrib/pgcrypto/px-crypt.c
@@ -0,0 +1,167 @@
+/*
+ * px-crypt.c
+ *		Wrapper for various crypt algorithms.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/px-crypt.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "px-crypt.h"
+
+
+static char *
+run_crypt_des(const char *psw, const char *salt,
+			  char *buf, unsigned len)
+{
+	char	   *res;
+
+	res = px_crypt_des(psw, salt);
+	if (strlen(res) > len - 1)
+		return NULL;
+	strcpy(buf, res);
+	return buf;
+}
+
+static char *
+run_crypt_md5(const char *psw, const char *salt,
+			  char *buf, unsigned len)
+{
+	char	   *res;
+
+	res = px_crypt_md5(psw, salt, buf, len);
+	return res;
+}
+
+static char *
+run_crypt_bf(const char *psw, const char *salt,
+			 char *buf, unsigned len)
+{
+	char	   *res;
+
+	res = _crypt_blowfish_rn(psw, salt, buf, len);
+	return res;
+}
+
+struct px_crypt_algo
+{
+	char	   *id;
+	unsigned	id_len;
+	char	   *(*crypt) (const char *psw, const char *salt,
+									  char *buf, unsigned len);
+};
+
+static const struct px_crypt_algo
+			px_crypt_list[] = {
+	{"$2a$", 4, run_crypt_bf},
+	{"$2x$", 4, run_crypt_bf},
+	{"$2$", 3, NULL},			/* N/A */
+	{"$1$", 3, run_crypt_md5},
+	{"_", 1, run_crypt_des},
+	{"", 0, run_crypt_des},
+	{NULL, 0, NULL}
+};
+
+char *
+px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
+{
+	const struct px_crypt_algo *c;
+
+	for (c = px_crypt_list; c->id; c++)
+	{
+		if (!c->id_len)
+			break;
+		if (strncmp(salt, c->id, c->id_len) == 0)
+			break;
+	}
+
+	if (c->crypt == NULL)
+		return NULL;
+
+	return c->crypt(psw, salt, buf, len);
+}
+
+/*
+ * salt generators
+ */
+
+struct generator
+{
+	char	   *name;
+	char	   *(*gen) (unsigned long count, const char *input, int size,
+									char *output, int output_size);
+	int			input_len;
+	int			def_rounds;
+	int			min_rounds;
+	int			max_rounds;
+};
+
+static struct generator gen_list[] = {
+	{"des", _crypt_gensalt_traditional_rn, 2, 0, 0, 0},
+	{"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0},
+	{"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF},
+	{"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31},
+	{NULL, NULL, 0, 0, 0, 0}
+};
+
+int
+px_gen_salt(const char *salt_type, char *buf, int rounds)
+{
+	int			res;
+	struct generator *g;
+	char	   *p;
+	char		rbuf[16];
+
+	for (g = gen_list; g->name; g++)
+		if (pg_strcasecmp(g->name, salt_type) == 0)
+			break;
+
+	if (g->name == NULL)
+		return PXE_UNKNOWN_SALT_ALGO;
+
+	if (g->def_rounds)
+	{
+		if (rounds == 0)
+			rounds = g->def_rounds;
+
+		if (rounds < g->min_rounds || rounds > g->max_rounds)
+			return PXE_BAD_SALT_ROUNDS;
+	}
+
+	res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
+	if (res < 0)
+		return res;
+
+	p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
+	memset(rbuf, 0, sizeof(rbuf));
+
+	if (p == NULL)
+		return PXE_BAD_SALT_ROUNDS;
+
+	return strlen(p);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/px-crypt.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/px-crypt.h b/contrib/pgcrypto/px-crypt.h
new file mode 100644
index 0000000..7dde9ab
--- /dev/null
+++ b/contrib/pgcrypto/px-crypt.h
@@ -0,0 +1,82 @@
+/*
+ * px-crypt.h
+ *		Header file for px_crypt().
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/px-crypt.h
+ */
+
+#ifndef _PX_CRYPT_H
+#define _PX_CRYPT_H
+
+/* max room for result */
+#define PX_MAX_CRYPT  128
+
+/* max salt returned by gen_salt() */
+#define PX_MAX_SALT_LEN		128
+
+/* default rounds for xdes salt */
+/* NetBSD bin/passwd/local_passwd.c has (29 * 25)*/
+#define PX_XDES_ROUNDS		(29 * 25)
+
+/* default for blowfish salt */
+#define PX_BF_ROUNDS		6
+
+/*
+ * main interface
+ */
+char	   *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen);
+int			px_gen_salt(const char *salt_type, char *dst, int rounds);
+
+/*
+ * internal functions
+ */
+
+/* crypt-gensalt.c */
+char *_crypt_gensalt_traditional_rn(unsigned long count,
+				 const char *input, int size, char *output, int output_size);
+char *_crypt_gensalt_extended_rn(unsigned long count,
+				 const char *input, int size, char *output, int output_size);
+char *_crypt_gensalt_md5_rn(unsigned long count,
+				 const char *input, int size, char *output, int output_size);
+char *_crypt_gensalt_blowfish_rn(unsigned long count,
+				 const char *input, int size, char *output, int output_size);
+
+/* disable 'extended DES crypt' */
+/* #define DISABLE_XDES */
+
+/* crypt-blowfish.c */
+char *_crypt_blowfish_rn(const char *key, const char *setting,
+				   char *output, int size);
+
+/* crypt-des.c */
+char	   *px_crypt_des(const char *key, const char *setting);
+
+/* crypt-md5.c */
+char *px_crypt_md5(const char *pw, const char *salt,
+			 char *dst, unsigned dstlen);
+
+#endif   /* _PX_CRYPT_H */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/px-hmac.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/px-hmac.c b/contrib/pgcrypto/px-hmac.c
new file mode 100644
index 0000000..36efabd
--- /dev/null
+++ b/contrib/pgcrypto/px-hmac.c
@@ -0,0 +1,177 @@
+/*
+ * px-hmac.c
+ *		HMAC implementation.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/px-hmac.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+
+#define HMAC_IPAD 0x36
+#define HMAC_OPAD 0x5C
+
+static unsigned
+hmac_result_size(PX_HMAC *h)
+{
+	return px_md_result_size(h->md);
+}
+
+static unsigned
+hmac_block_size(PX_HMAC *h)
+{
+	return px_md_block_size(h->md);
+}
+
+static void
+hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen)
+{
+	unsigned	bs,
+				i;
+	uint8	   *keybuf;
+	PX_MD	   *md = h->md;
+
+	bs = px_md_block_size(md);
+	keybuf = px_alloc(bs);
+	memset(keybuf, 0, bs);
+
+	if (klen > bs)
+	{
+		px_md_update(md, key, klen);
+		px_md_finish(md, keybuf);
+		px_md_reset(md);
+	}
+	else
+		memcpy(keybuf, key, klen);
+
+	for (i = 0; i < bs; i++)
+	{
+		h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD;
+		h->p.opad[i] = keybuf[i] ^ HMAC_OPAD;
+	}
+
+	memset(keybuf, 0, bs);
+	px_free(keybuf);
+
+	px_md_update(md, h->p.ipad, bs);
+}
+
+static void
+hmac_reset(PX_HMAC *h)
+{
+	PX_MD	   *md = h->md;
+	unsigned	bs = px_md_block_size(md);
+
+	px_md_reset(md);
+	px_md_update(md, h->p.ipad, bs);
+}
+
+static void
+hmac_update(PX_HMAC *h, const uint8 *data, unsigned dlen)
+{
+	px_md_update(h->md, data, dlen);
+}
+
+static void
+hmac_finish(PX_HMAC *h, uint8 *dst)
+{
+	PX_MD	   *md = h->md;
+	unsigned	bs,
+				hlen;
+	uint8	   *buf;
+
+	bs = px_md_block_size(md);
+	hlen = px_md_result_size(md);
+
+	buf = px_alloc(hlen);
+
+	px_md_finish(md, buf);
+
+	px_md_reset(md);
+	px_md_update(md, h->p.opad, bs);
+	px_md_update(md, buf, hlen);
+	px_md_finish(md, dst);
+
+	memset(buf, 0, hlen);
+	px_free(buf);
+}
+
+static void
+hmac_free(PX_HMAC *h)
+{
+	unsigned	bs;
+
+	bs = px_md_block_size(h->md);
+	px_md_free(h->md);
+
+	memset(h->p.ipad, 0, bs);
+	memset(h->p.opad, 0, bs);
+	px_free(h->p.ipad);
+	px_free(h->p.opad);
+	px_free(h);
+}
+
+
+/* PUBLIC FUNCTIONS */
+
+int
+px_find_hmac(const char *name, PX_HMAC **res)
+{
+	int			err;
+	PX_MD	   *md;
+	PX_HMAC    *h;
+	unsigned	bs;
+
+	err = px_find_digest(name, &md);
+	if (err)
+		return err;
+
+	bs = px_md_block_size(md);
+	if (bs < 2)
+	{
+		px_md_free(md);
+		return PXE_HASH_UNUSABLE_FOR_HMAC;
+	}
+
+	h = px_alloc(sizeof(*h));
+	h->p.ipad = px_alloc(bs);
+	h->p.opad = px_alloc(bs);
+	h->md = md;
+
+	h->result_size = hmac_result_size;
+	h->block_size = hmac_block_size;
+	h->reset = hmac_reset;
+	h->update = hmac_update;
+	h->finish = hmac_finish;
+	h->free = hmac_free;
+	h->init = hmac_init;
+
+	*res = h;
+
+	return 0;
+}


[07/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/internal.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c
new file mode 100644
index 0000000..a02c943
--- /dev/null
+++ b/contrib/pgcrypto/internal.c
@@ -0,0 +1,688 @@
+/*
+ * internal.c
+ *		Wrapper for builtin functions
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/internal.c
+ */
+
+#include "postgres.h"
+
+#include <time.h>
+
+#include "px.h"
+#include "md5.h"
+#include "sha1.h"
+#include "blf.h"
+#include "rijndael.h"
+#include "fortuna.h"
+
+/*
+ * System reseeds should be separated at least this much.
+ */
+#define SYSTEM_RESEED_MIN			(20*60)		/* 20 min */
+/*
+ * How often to roll dice.
+ */
+#define SYSTEM_RESEED_CHECK_TIME	(10*60)		/* 10 min */
+/*
+ * The chance is x/256 that the reseed happens.
+ */
+#define SYSTEM_RESEED_CHANCE		(4) /* 256/4 * 10min ~ 10h */
+
+/*
+ * If this much time has passed, force reseed.
+ */
+#define SYSTEM_RESEED_MAX			(12*60*60)	/* 12h */
+
+
+#ifndef MD5_DIGEST_LENGTH
+#define MD5_DIGEST_LENGTH 16
+#endif
+
+#ifndef SHA1_DIGEST_LENGTH
+#ifdef SHA1_RESULTLEN
+#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN
+#else
+#define SHA1_DIGEST_LENGTH 20
+#endif
+#endif
+
+#define SHA1_BLOCK_SIZE 64
+#define MD5_BLOCK_SIZE 64
+
+static void init_md5(PX_MD *h);
+static void init_sha1(PX_MD *h);
+
+void		init_sha224(PX_MD *h);
+void		init_sha256(PX_MD *h);
+void		init_sha384(PX_MD *h);
+void		init_sha512(PX_MD *h);
+
+struct int_digest
+{
+	char	   *name;
+	void		(*init) (PX_MD *h);
+};
+
+static const struct int_digest
+			int_digest_list[] = {
+	{"md5", init_md5},
+	{"sha1", init_sha1},
+	{"sha224", init_sha224},
+	{"sha256", init_sha256},
+	{"sha384", init_sha384},
+	{"sha512", init_sha512},
+	{NULL, NULL}
+};
+
+/* MD5 */
+
+static unsigned
+int_md5_len(PX_MD *h)
+{
+	return MD5_DIGEST_LENGTH;
+}
+
+static unsigned
+int_md5_block_len(PX_MD *h)
+{
+	return MD5_BLOCK_SIZE;
+}
+
+static void
+int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen)
+{
+	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
+
+	MD5Update(ctx, data, dlen);
+}
+
+static void
+int_md5_reset(PX_MD *h)
+{
+	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
+
+	MD5Init(ctx);
+}
+
+static void
+int_md5_finish(PX_MD *h, uint8 *dst)
+{
+	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
+
+	MD5Final(dst, ctx);
+}
+
+static void
+int_md5_free(PX_MD *h)
+{
+	MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
+
+	memset(ctx, 0, sizeof(*ctx));
+	px_free(ctx);
+	px_free(h);
+}
+
+/* SHA1 */
+
+static unsigned
+int_sha1_len(PX_MD *h)
+{
+	return SHA1_DIGEST_LENGTH;
+}
+
+static unsigned
+int_sha1_block_len(PX_MD *h)
+{
+	return SHA1_BLOCK_SIZE;
+}
+
+static void
+int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen)
+{
+	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
+
+	SHA1Update(ctx, data, dlen);
+}
+
+static void
+int_sha1_reset(PX_MD *h)
+{
+	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
+
+	SHA1Init(ctx);
+}
+
+static void
+int_sha1_finish(PX_MD *h, uint8 *dst)
+{
+	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
+
+	SHA1Final(dst, ctx);
+}
+
+static void
+int_sha1_free(PX_MD *h)
+{
+	SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
+
+	memset(ctx, 0, sizeof(*ctx));
+	px_free(ctx);
+	px_free(h);
+}
+
+/* init functions */
+
+static void
+init_md5(PX_MD *md)
+{
+	MD5_CTX    *ctx;
+
+	ctx = px_alloc(sizeof(*ctx));
+	memset(ctx, 0, sizeof(*ctx));
+
+	md->p.ptr = ctx;
+
+	md->result_size = int_md5_len;
+	md->block_size = int_md5_block_len;
+	md->reset = int_md5_reset;
+	md->update = int_md5_update;
+	md->finish = int_md5_finish;
+	md->free = int_md5_free;
+
+	md->reset(md);
+}
+
+static void
+init_sha1(PX_MD *md)
+{
+	SHA1_CTX   *ctx;
+
+	ctx = px_alloc(sizeof(*ctx));
+	memset(ctx, 0, sizeof(*ctx));
+
+	md->p.ptr = ctx;
+
+	md->result_size = int_sha1_len;
+	md->block_size = int_sha1_block_len;
+	md->reset = int_sha1_reset;
+	md->update = int_sha1_update;
+	md->finish = int_sha1_finish;
+	md->free = int_sha1_free;
+
+	md->reset(md);
+}
+
+/*
+ * ciphers generally
+ */
+
+#define INT_MAX_KEY		(512/8)
+#define INT_MAX_IV		(128/8)
+
+struct int_ctx
+{
+	uint8		keybuf[INT_MAX_KEY];
+	uint8		iv[INT_MAX_IV];
+	union
+	{
+		BlowfishContext bf;
+		rijndael_ctx rj;
+	}			ctx;
+	unsigned	keylen;
+	int			is_init;
+	int			mode;
+};
+
+static void
+intctx_free(PX_Cipher *c)
+{
+	struct int_ctx *cx = (struct int_ctx *) c->ptr;
+
+	if (cx)
+	{
+		memset(cx, 0, sizeof *cx);
+		px_free(cx);
+	}
+	px_free(c);
+}
+
+/*
+ * AES/rijndael
+ */
+
+#define MODE_ECB 0
+#define MODE_CBC 1
+
+static unsigned
+rj_block_size(PX_Cipher *c)
+{
+	return 128 / 8;
+}
+
+static unsigned
+rj_key_size(PX_Cipher *c)
+{
+	return 256 / 8;
+}
+
+static unsigned
+rj_iv_size(PX_Cipher *c)
+{
+	return 128 / 8;
+}
+
+static int
+rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
+{
+	struct int_ctx *cx = (struct int_ctx *) c->ptr;
+
+	if (klen <= 128 / 8)
+		cx->keylen = 128 / 8;
+	else if (klen <= 192 / 8)
+		cx->keylen = 192 / 8;
+	else if (klen <= 256 / 8)
+		cx->keylen = 256 / 8;
+	else
+		return PXE_KEY_TOO_BIG;
+
+	memcpy(&cx->keybuf, key, klen);
+
+	if (iv)
+		memcpy(cx->iv, iv, 128 / 8);
+
+	return 0;
+}
+
+static int
+rj_real_init(struct int_ctx * cx, int dir)
+{
+	aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir);
+	return 0;
+}
+
+static int
+rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	struct int_ctx *cx = (struct int_ctx *) c->ptr;
+
+	if (!cx->is_init)
+	{
+		if (rj_real_init(cx, 1))
+			return PXE_CIPHER_INIT;
+	}
+
+	if (dlen == 0)
+		return 0;
+
+	if (dlen & 15)
+		return PXE_NOTBLOCKSIZE;
+
+	memcpy(res, data, dlen);
+
+	if (cx->mode == MODE_CBC)
+	{
+		aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen);
+		memcpy(cx->iv, res + dlen - 16, 16);
+	}
+	else
+		aes_ecb_encrypt(&cx->ctx.rj, res, dlen);
+
+	return 0;
+}
+
+static int
+rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	struct int_ctx *cx = (struct int_ctx *) c->ptr;
+
+	if (!cx->is_init)
+		if (rj_real_init(cx, 0))
+			return PXE_CIPHER_INIT;
+
+	if (dlen == 0)
+		return 0;
+
+	if (dlen & 15)
+		return PXE_NOTBLOCKSIZE;
+
+	memcpy(res, data, dlen);
+
+	if (cx->mode == MODE_CBC)
+	{
+		aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen);
+		memcpy(cx->iv, data + dlen - 16, 16);
+	}
+	else
+		aes_ecb_decrypt(&cx->ctx.rj, res, dlen);
+
+	return 0;
+}
+
+/*
+ * initializers
+ */
+
+static PX_Cipher *
+rj_load(int mode)
+{
+	PX_Cipher  *c;
+	struct int_ctx *cx;
+
+	c = px_alloc(sizeof *c);
+	memset(c, 0, sizeof *c);
+
+	c->block_size = rj_block_size;
+	c->key_size = rj_key_size;
+	c->iv_size = rj_iv_size;
+	c->init = rj_init;
+	c->encrypt = rj_encrypt;
+	c->decrypt = rj_decrypt;
+	c->free = intctx_free;
+
+	cx = px_alloc(sizeof *cx);
+	memset(cx, 0, sizeof *cx);
+	cx->mode = mode;
+
+	c->ptr = cx;
+	return c;
+}
+
+/*
+ * blowfish
+ */
+
+static unsigned
+bf_block_size(PX_Cipher *c)
+{
+	return 8;
+}
+
+static unsigned
+bf_key_size(PX_Cipher *c)
+{
+	return 448 / 8;
+}
+
+static unsigned
+bf_iv_size(PX_Cipher *c)
+{
+	return 8;
+}
+
+static int
+bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
+{
+	struct int_ctx *cx = (struct int_ctx *) c->ptr;
+
+	blowfish_setkey(&cx->ctx.bf, key, klen);
+	if (iv)
+		blowfish_setiv(&cx->ctx.bf, iv);
+
+	return 0;
+}
+
+static int
+bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	struct int_ctx *cx = (struct int_ctx *) c->ptr;
+	BlowfishContext *bfctx = &cx->ctx.bf;
+
+	if (dlen == 0)
+		return 0;
+
+	if (dlen & 7)
+		return PXE_NOTBLOCKSIZE;
+
+	memcpy(res, data, dlen);
+	switch (cx->mode)
+	{
+		case MODE_ECB:
+			blowfish_encrypt_ecb(res, dlen, bfctx);
+			break;
+		case MODE_CBC:
+			blowfish_encrypt_cbc(res, dlen, bfctx);
+			break;
+	}
+	return 0;
+}
+
+static int
+bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	struct int_ctx *cx = (struct int_ctx *) c->ptr;
+	BlowfishContext *bfctx = &cx->ctx.bf;
+
+	if (dlen == 0)
+		return 0;
+
+	if (dlen & 7)
+		return PXE_NOTBLOCKSIZE;
+
+	memcpy(res, data, dlen);
+	switch (cx->mode)
+	{
+		case MODE_ECB:
+			blowfish_decrypt_ecb(res, dlen, bfctx);
+			break;
+		case MODE_CBC:
+			blowfish_decrypt_cbc(res, dlen, bfctx);
+			break;
+	}
+	return 0;
+}
+
+static PX_Cipher *
+bf_load(int mode)
+{
+	PX_Cipher  *c;
+	struct int_ctx *cx;
+
+	c = px_alloc(sizeof *c);
+	memset(c, 0, sizeof *c);
+
+	c->block_size = bf_block_size;
+	c->key_size = bf_key_size;
+	c->iv_size = bf_iv_size;
+	c->init = bf_init;
+	c->encrypt = bf_encrypt;
+	c->decrypt = bf_decrypt;
+	c->free = intctx_free;
+
+	cx = px_alloc(sizeof *cx);
+	memset(cx, 0, sizeof *cx);
+	cx->mode = mode;
+	c->ptr = cx;
+	return c;
+}
+
+/* ciphers */
+
+static PX_Cipher *
+rj_128_ecb(void)
+{
+	return rj_load(MODE_ECB);
+}
+
+static PX_Cipher *
+rj_128_cbc(void)
+{
+	return rj_load(MODE_CBC);
+}
+
+static PX_Cipher *
+bf_ecb_load(void)
+{
+	return bf_load(MODE_ECB);
+}
+
+static PX_Cipher *
+bf_cbc_load(void)
+{
+	return bf_load(MODE_CBC);
+}
+
+struct int_cipher
+{
+	char	   *name;
+	PX_Cipher  *(*load) (void);
+};
+
+static const struct int_cipher
+			int_ciphers[] = {
+	{"bf-cbc", bf_cbc_load},
+	{"bf-ecb", bf_ecb_load},
+	{"aes-128-cbc", rj_128_cbc},
+	{"aes-128-ecb", rj_128_ecb},
+	{NULL, NULL}
+};
+
+static const PX_Alias int_aliases[] = {
+	{"bf", "bf-cbc"},
+	{"blowfish", "bf-cbc"},
+	{"aes", "aes-128-cbc"},
+	{"aes-ecb", "aes-128-ecb"},
+	{"aes-cbc", "aes-128-cbc"},
+	{"aes-128", "aes-128-cbc"},
+	{"rijndael", "aes-128-cbc"},
+	{"rijndael-128", "aes-128-cbc"},
+	{NULL, NULL}
+};
+
+/* PUBLIC FUNCTIONS */
+
+int
+px_find_digest(const char *name, PX_MD **res)
+{
+	const struct int_digest *p;
+	PX_MD	   *h;
+
+	for (p = int_digest_list; p->name; p++)
+		if (pg_strcasecmp(p->name, name) == 0)
+		{
+			h = px_alloc(sizeof(*h));
+			p->init(h);
+
+			*res = h;
+
+			return 0;
+		}
+	return PXE_NO_HASH;
+}
+
+int
+px_find_cipher(const char *name, PX_Cipher **res)
+{
+	int			i;
+	PX_Cipher  *c = NULL;
+
+	name = px_resolve_alias(int_aliases, name);
+
+	for (i = 0; int_ciphers[i].name; i++)
+		if (strcmp(int_ciphers[i].name, name) == 0)
+		{
+			c = int_ciphers[i].load();
+			break;
+		}
+
+	if (c == NULL)
+		return PXE_NO_CIPHER;
+
+	*res = c;
+	return 0;
+}
+
+/*
+ * Randomness provider
+ */
+
+/*
+ * Use always strong randomness.
+ */
+int
+px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
+{
+	return px_get_random_bytes(dst, count);
+}
+
+static time_t seed_time = 0;
+static time_t check_time = 0;
+
+static void
+system_reseed(void)
+{
+	uint8		buf[1024];
+	int			n;
+	time_t		t;
+	int			skip = 1;
+
+	t = time(NULL);
+
+	if (seed_time == 0)
+		skip = 0;
+	else if ((t - seed_time) < SYSTEM_RESEED_MIN)
+		skip = 1;
+	else if ((t - seed_time) > SYSTEM_RESEED_MAX)
+		skip = 0;
+	else if (check_time == 0 ||
+			 (t - check_time) > SYSTEM_RESEED_CHECK_TIME)
+	{
+		check_time = t;
+
+		/* roll dice */
+		px_get_random_bytes(buf, 1);
+		skip = buf[0] >= SYSTEM_RESEED_CHANCE;
+	}
+	/* clear 1 byte */
+	memset(buf, 0, sizeof(buf));
+
+	if (skip)
+		return;
+
+	n = px_acquire_system_randomness(buf);
+	if (n > 0)
+		fortuna_add_entropy(buf, n);
+
+	seed_time = t;
+	memset(buf, 0, sizeof(buf));
+}
+
+int
+px_get_random_bytes(uint8 *dst, unsigned count)
+{
+	system_reseed();
+	fortuna_get_bytes(count, dst);
+	return 0;
+}
+
+int
+px_add_entropy(const uint8 *data, unsigned count)
+{
+	system_reseed();
+	fortuna_add_entropy(data, count);
+	return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/mbuf.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/mbuf.c b/contrib/pgcrypto/mbuf.c
new file mode 100644
index 0000000..a2c5293
--- /dev/null
+++ b/contrib/pgcrypto/mbuf.c
@@ -0,0 +1,563 @@
+/*
+ * mbuf.c
+ *		Memory buffer operations.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/mbuf.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+#include "mbuf.h"
+
+#define STEP  (16*1024)
+
+struct MBuf
+{
+	uint8	   *data;
+	uint8	   *data_end;
+	uint8	   *read_pos;
+	uint8	   *buf_end;
+	bool		no_write;
+	bool		own_data;
+};
+
+int
+mbuf_avail(MBuf *mbuf)
+{
+	return mbuf->data_end - mbuf->read_pos;
+}
+
+int
+mbuf_size(MBuf *mbuf)
+{
+	return mbuf->data_end - mbuf->data;
+}
+
+int
+mbuf_tell(MBuf *mbuf)
+{
+	return mbuf->read_pos - mbuf->data;
+}
+
+int
+mbuf_free(MBuf *mbuf)
+{
+	if (mbuf->own_data)
+	{
+		memset(mbuf->data, 0, mbuf->buf_end - mbuf->data);
+		px_free(mbuf->data);
+	}
+	px_free(mbuf);
+	return 0;
+}
+
+static void
+prepare_room(MBuf *mbuf, int block_len)
+{
+	uint8	   *newbuf;
+	unsigned	newlen;
+
+	if (mbuf->data_end + block_len <= mbuf->buf_end)
+		return;
+
+	newlen = (mbuf->buf_end - mbuf->data)
+		+ ((block_len + STEP + STEP - 1) & -STEP);
+
+	newbuf = px_realloc(mbuf->data, newlen);
+
+	mbuf->buf_end = newbuf + newlen;
+	mbuf->data_end = newbuf + (mbuf->data_end - mbuf->data);
+	mbuf->read_pos = newbuf + (mbuf->read_pos - mbuf->data);
+	mbuf->data = newbuf;
+
+	return;
+}
+
+int
+mbuf_append(MBuf *dst, const uint8 *buf, int len)
+{
+	if (dst->no_write)
+	{
+		px_debug("mbuf_append: no_write");
+		return PXE_BUG;
+	}
+
+	prepare_room(dst, len);
+
+	memcpy(dst->data_end, buf, len);
+	dst->data_end += len;
+
+	return 0;
+}
+
+MBuf *
+mbuf_create(int len)
+{
+	MBuf	   *mbuf;
+
+	if (!len)
+		len = 8192;
+
+	mbuf = px_alloc(sizeof *mbuf);
+	mbuf->data = px_alloc(len);
+	mbuf->buf_end = mbuf->data + len;
+	mbuf->data_end = mbuf->data;
+	mbuf->read_pos = mbuf->data;
+
+	mbuf->no_write = false;
+	mbuf->own_data = true;
+
+	return mbuf;
+}
+
+MBuf *
+mbuf_create_from_data(uint8 *data, int len)
+{
+	MBuf	   *mbuf;
+
+	mbuf = px_alloc(sizeof *mbuf);
+	mbuf->data = (uint8 *) data;
+	mbuf->buf_end = mbuf->data + len;
+	mbuf->data_end = mbuf->data + len;
+	mbuf->read_pos = mbuf->data;
+
+	mbuf->no_write = true;
+	mbuf->own_data = false;
+
+	return mbuf;
+}
+
+
+int
+mbuf_grab(MBuf *mbuf, int len, uint8 **data_p)
+{
+	if (len > mbuf_avail(mbuf))
+		len = mbuf_avail(mbuf);
+
+	mbuf->no_write = true;
+
+	*data_p = mbuf->read_pos;
+	mbuf->read_pos += len;
+	return len;
+}
+
+int
+mbuf_rewind(MBuf *mbuf)
+{
+	mbuf->read_pos = mbuf->data;
+	return 0;
+}
+
+int
+mbuf_steal_data(MBuf *mbuf, uint8 **data_p)
+{
+	int			len = mbuf_size(mbuf);
+
+	mbuf->no_write = true;
+	mbuf->own_data = false;
+
+	*data_p = mbuf->data;
+
+	mbuf->data = mbuf->data_end = mbuf->read_pos = mbuf->buf_end = NULL;
+
+	return len;
+}
+
+/*
+ * PullFilter
+ */
+
+struct PullFilter
+{
+	PullFilter *src;
+	const PullFilterOps *op;
+	int			buflen;
+	uint8	   *buf;
+	int			pos;
+	void	   *priv;
+};
+
+int
+pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFilter *src)
+{
+	PullFilter *pf;
+	void	   *priv;
+	int			res;
+
+	if (op->init != NULL)
+	{
+		res = op->init(&priv, init_arg, src);
+		if (res < 0)
+			return res;
+	}
+	else
+	{
+		priv = init_arg;
+		res = 0;
+	}
+
+	pf = px_alloc(sizeof(*pf));
+	memset(pf, 0, sizeof(*pf));
+	pf->buflen = res;
+	pf->op = op;
+	pf->priv = priv;
+	pf->src = src;
+	if (pf->buflen > 0)
+	{
+		pf->buf = px_alloc(pf->buflen);
+		pf->pos = 0;
+	}
+	else
+	{
+		pf->buf = NULL;
+		pf->pos = 0;
+	}
+	*pf_p = pf;
+	return 0;
+}
+
+void
+pullf_free(PullFilter *pf)
+{
+	if (pf->op->free)
+		pf->op->free(pf->priv);
+
+	if (pf->buf)
+	{
+		memset(pf->buf, 0, pf->buflen);
+		px_free(pf->buf);
+	}
+
+	memset(pf, 0, sizeof(*pf));
+	px_free(pf);
+}
+
+/* may return less data than asked, 0 means eof */
+int
+pullf_read(PullFilter *pf, int len, uint8 **data_p)
+{
+	int			res;
+
+	if (pf->op->pull)
+	{
+		if (pf->buflen && len > pf->buflen)
+			len = pf->buflen;
+		res = pf->op->pull(pf->priv, pf->src, len, data_p,
+						   pf->buf, pf->buflen);
+	}
+	else
+		res = pullf_read(pf->src, len, data_p);
+	return res;
+}
+
+int
+pullf_read_max(PullFilter *pf, int len, uint8 **data_p, uint8 *tmpbuf)
+{
+	int			res,
+				total;
+	uint8	   *tmp;
+
+	res = pullf_read(pf, len, data_p);
+	if (res <= 0 || res == len)
+		return res;
+
+	/* read was shorter, use tmpbuf */
+	memcpy(tmpbuf, *data_p, res);
+	*data_p = tmpbuf;
+	len -= res;
+	total = res;
+
+	while (len > 0)
+	{
+		res = pullf_read(pf, len, &tmp);
+		if (res < 0)
+		{
+			/* so the caller must clear only on success */
+			memset(tmpbuf, 0, total);
+			return res;
+		}
+		if (res == 0)
+			break;
+		memcpy(tmpbuf + total, tmp, res);
+		total += res;
+	}
+	return total;
+}
+
+/*
+ * caller wants exatly len bytes and dont bother with references
+ */
+int
+pullf_read_fixed(PullFilter *src, int len, uint8 *dst)
+{
+	int			res;
+	uint8	   *p;
+
+	res = pullf_read_max(src, len, &p, dst);
+	if (res < 0)
+		return res;
+	if (res != len)
+	{
+		px_debug("pullf_read_fixed: need=%d got=%d", len, res);
+		return PXE_MBUF_SHORT_READ;
+	}
+	if (p != dst)
+		memcpy(dst, p, len);
+	return 0;
+}
+
+/*
+ * read from MBuf
+ */
+static int
+pull_from_mbuf(void *arg, PullFilter *src, int len,
+			   uint8 **data_p, uint8 *buf, int buflen)
+{
+	MBuf	   *mbuf = arg;
+
+	return mbuf_grab(mbuf, len, data_p);
+}
+
+static const struct PullFilterOps mbuf_reader = {
+	NULL, pull_from_mbuf, NULL
+};
+
+int
+pullf_create_mbuf_reader(PullFilter **mp_p, MBuf *src)
+{
+	return pullf_create(mp_p, &mbuf_reader, src, NULL);
+}
+
+
+/*
+ * PushFilter
+ */
+
+struct PushFilter
+{
+	PushFilter *next;
+	const PushFilterOps *op;
+	int			block_size;
+	uint8	   *buf;
+	int			pos;
+	void	   *priv;
+};
+
+int
+pushf_create(PushFilter **mp_p, const PushFilterOps *op, void *init_arg, PushFilter *next)
+{
+	PushFilter *mp;
+	void	   *priv;
+	int			res;
+
+	if (op->init != NULL)
+	{
+		res = op->init(next, init_arg, &priv);
+		if (res < 0)
+			return res;
+	}
+	else
+	{
+		priv = init_arg;
+		res = 0;
+	}
+
+	mp = px_alloc(sizeof(*mp));
+	memset(mp, 0, sizeof(*mp));
+	mp->block_size = res;
+	mp->op = op;
+	mp->priv = priv;
+	mp->next = next;
+	if (mp->block_size > 0)
+	{
+		mp->buf = px_alloc(mp->block_size);
+		mp->pos = 0;
+	}
+	else
+	{
+		mp->buf = NULL;
+		mp->pos = 0;
+	}
+	*mp_p = mp;
+	return 0;
+}
+
+void
+pushf_free(PushFilter *mp)
+{
+	if (mp->op->free)
+		mp->op->free(mp->priv);
+
+	if (mp->buf)
+	{
+		memset(mp->buf, 0, mp->block_size);
+		px_free(mp->buf);
+	}
+
+	memset(mp, 0, sizeof(*mp));
+	px_free(mp);
+}
+
+void
+pushf_free_all(PushFilter *mp)
+{
+	PushFilter *tmp;
+
+	while (mp)
+	{
+		tmp = mp->next;
+		pushf_free(mp);
+		mp = tmp;
+	}
+}
+
+static int
+wrap_process(PushFilter *mp, const uint8 *data, int len)
+{
+	int			res;
+
+	if (mp->op->push != NULL)
+		res = mp->op->push(mp->next, mp->priv, data, len);
+	else
+		res = pushf_write(mp->next, data, len);
+	if (res > 0)
+		return PXE_BUG;
+	return res;
+}
+
+/* consumes all data, returns len on success */
+int
+pushf_write(PushFilter *mp, const uint8 *data, int len)
+{
+	int			need,
+				res;
+
+	/*
+	 * no buffering
+	 */
+	if (mp->block_size <= 0)
+		return wrap_process(mp, data, len);
+
+	/*
+	 * try to empty buffer
+	 */
+	need = mp->block_size - mp->pos;
+	if (need > 0)
+	{
+		if (len < need)
+		{
+			memcpy(mp->buf + mp->pos, data, len);
+			mp->pos += len;
+			return 0;
+		}
+		memcpy(mp->buf + mp->pos, data, need);
+		len -= need;
+		data += need;
+	}
+
+	/*
+	 * buffer full, process
+	 */
+	res = wrap_process(mp, mp->buf, mp->block_size);
+	if (res < 0)
+		return res;
+	mp->pos = 0;
+
+	/*
+	 * now process directly from data
+	 */
+	while (len > 0)
+	{
+		if (len > mp->block_size)
+		{
+			res = wrap_process(mp, data, mp->block_size);
+			if (res < 0)
+				return res;
+			data += mp->block_size;
+			len -= mp->block_size;
+		}
+		else
+		{
+			memcpy(mp->buf, data, len);
+			mp->pos += len;
+			break;
+		}
+	}
+	return 0;
+}
+
+int
+pushf_flush(PushFilter *mp)
+{
+	int			res;
+
+	while (mp)
+	{
+		if (mp->block_size > 0)
+		{
+			res = wrap_process(mp, mp->buf, mp->pos);
+			if (res < 0)
+				return res;
+		}
+
+		if (mp->op->flush)
+		{
+			res = mp->op->flush(mp->next, mp->priv);
+			if (res < 0)
+				return res;
+		}
+
+		mp = mp->next;
+	}
+	return 0;
+}
+
+
+/*
+ * write to MBuf
+ */
+static int
+push_into_mbuf(PushFilter *next, void *arg, const uint8 *data, int len)
+{
+	int			res = 0;
+	MBuf	   *mbuf = arg;
+
+	if (len > 0)
+		res = mbuf_append(mbuf, data, len);
+	return res < 0 ? res : 0;
+}
+
+static const struct PushFilterOps mbuf_filter = {
+	NULL, push_into_mbuf, NULL, NULL
+};
+
+int
+pushf_create_mbuf_writer(PushFilter **res, MBuf *dst)
+{
+	return pushf_create(res, &mbuf_filter, dst, NULL);
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/mbuf.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/mbuf.h b/contrib/pgcrypto/mbuf.h
new file mode 100644
index 0000000..da016c0
--- /dev/null
+++ b/contrib/pgcrypto/mbuf.h
@@ -0,0 +1,124 @@
+/*
+ * mbuf.h
+ *		Memory buffer operations.
+ *
+ * Copyright (c) 2005 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/mbuf.h
+ */
+
+#ifndef __PX_MBUF_H
+#define __PX_MBUF_H
+
+typedef struct MBuf MBuf;
+typedef struct PushFilter PushFilter;
+typedef struct PullFilter PullFilter;
+typedef struct PushFilterOps PushFilterOps;
+typedef struct PullFilterOps PullFilterOps;
+
+struct PushFilterOps
+{
+	/*
+	 * should return needed buffer size, 0- no buffering, <0 on error if NULL,
+	 * no buffering, and priv=init_arg
+	 */
+	int			(*init) (PushFilter *next, void *init_arg, void **priv_p);
+
+	/*
+	 * send data to next.  should consume all? if null, it will be simply
+	 * copied (in-place) returns 0 on error
+	 */
+	int			(*push) (PushFilter *next, void *priv,
+									 const uint8 *src, int len);
+	int			(*flush) (PushFilter *next, void *priv);
+	void		(*free) (void *priv);
+};
+
+struct PullFilterOps
+{
+	/*
+	 * should return needed buffer size, 0- no buffering, <0 on error if NULL,
+	 * no buffering, and priv=init_arg
+	 */
+	int			(*init) (void **priv_p, void *init_arg, PullFilter *src);
+
+	/*
+	 * request data from src, put result ptr to data_p can use ptr from src or
+	 * use buf as work area if NULL in-place copy
+	 */
+	int			(*pull) (void *priv, PullFilter *src, int len,
+									 uint8 **data_p, uint8 *buf, int buflen);
+	void		(*free) (void *priv);
+};
+
+/*
+ * Memory buffer
+ */
+MBuf	   *mbuf_create(int len);
+MBuf	   *mbuf_create_from_data(uint8 *data, int len);
+int			mbuf_tell(MBuf *mbuf);
+int			mbuf_avail(MBuf *mbuf);
+int			mbuf_size(MBuf *mbuf);
+int			mbuf_grab(MBuf *mbuf, int len, uint8 **data_p);
+int			mbuf_steal_data(MBuf *mbuf, uint8 **data_p);
+int			mbuf_append(MBuf *dst, const uint8 *buf, int cnt);
+int			mbuf_rewind(MBuf *mbuf);
+int			mbuf_free(MBuf *mbuf);
+
+/*
+ * Push filter
+ */
+int pushf_create(PushFilter **res, const PushFilterOps *ops, void *init_arg,
+			 PushFilter *next);
+int			pushf_write(PushFilter *mp, const uint8 *data, int len);
+void		pushf_free_all(PushFilter *mp);
+void		pushf_free(PushFilter *mp);
+int			pushf_flush(PushFilter *mp);
+
+int			pushf_create_mbuf_writer(PushFilter **mp_p, MBuf *mbuf);
+
+/*
+ * Pull filter
+ */
+int pullf_create(PullFilter **res, const PullFilterOps *ops,
+			 void *init_arg, PullFilter *src);
+int			pullf_read(PullFilter *mp, int len, uint8 **data_p);
+int pullf_read_max(PullFilter *mp, int len,
+			   uint8 **data_p, uint8 *tmpbuf);
+void		pullf_free(PullFilter *mp);
+int			pullf_read_fixed(PullFilter *src, int len, uint8 *dst);
+
+int			pullf_create_mbuf_reader(PullFilter **pf_p, MBuf *mbuf);
+
+#define GETBYTE(pf, dst) \
+	do { \
+		uint8 __b; \
+		int __res = pullf_read_fixed(pf, 1, &__b); \
+		if (__res < 0) \
+			return __res; \
+		(dst) = __b; \
+	} while (0)
+
+#endif   /* __PX_MBUF_H */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/md5.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c
new file mode 100644
index 0000000..08227a8
--- /dev/null
+++ b/contrib/pgcrypto/md5.c
@@ -0,0 +1,397 @@
+/*	   $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $	   */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 project nor the names of its contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/md5.c
+ */
+
+#include "postgres.h"
+
+#include <sys/param.h>
+
+#include "md5.h"
+
+#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
+
+#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
+#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
+#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
+#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
+
+#define ROUND1(a, b, c, d, k, s, i) \
+do { \
+	(a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
+	(a) = SHIFT((a), (s)); \
+	(a) = (b) + (a); \
+} while (0)
+
+#define ROUND2(a, b, c, d, k, s, i) \
+do { \
+	(a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
+	(a) = SHIFT((a), (s)); \
+	(a) = (b) + (a); \
+} while (0)
+
+#define ROUND3(a, b, c, d, k, s, i) \
+do { \
+	(a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
+	(a) = SHIFT((a), (s)); \
+	(a) = (b) + (a); \
+} while (0)
+
+#define ROUND4(a, b, c, d, k, s, i) \
+do { \
+	(a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
+	(a) = SHIFT((a), (s)); \
+	(a) = (b) + (a); \
+} while (0)
+
+#define Sa	 7
+#define Sb	12
+#define Sc	17
+#define Sd	22
+
+#define Se	 5
+#define Sf	 9
+#define Sg	14
+#define Sh	20
+
+#define Si	 4
+#define Sj	11
+#define Sk	16
+#define Sl	23
+
+#define Sm	 6
+#define Sn	10
+#define So	15
+#define Sp	21
+
+#define MD5_A0	0x67452301
+#define MD5_B0	0xefcdab89
+#define MD5_C0	0x98badcfe
+#define MD5_D0	0x10325476
+
+/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
+static const uint32 T[65] = {
+	0,
+	0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+	0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+	0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+	0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+
+	0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+	0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
+	0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+	0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+
+	0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+	0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+	0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
+	0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+
+	0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+	0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+	0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+	0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
+};
+
+static const uint8 md5_paddat[MD5_BUFLEN] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static void md5_calc(uint8 *, md5_ctxt *);
+
+void
+md5_init(md5_ctxt *ctxt)
+{
+	ctxt->md5_n = 0;
+	ctxt->md5_i = 0;
+	ctxt->md5_sta = MD5_A0;
+	ctxt->md5_stb = MD5_B0;
+	ctxt->md5_stc = MD5_C0;
+	ctxt->md5_std = MD5_D0;
+	memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf));
+}
+
+void
+md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len)
+{
+	unsigned int gap,
+				i;
+
+	ctxt->md5_n += len * 8;		/* byte to bit */
+	gap = MD5_BUFLEN - ctxt->md5_i;
+
+	if (len >= gap)
+	{
+		memmove(ctxt->md5_buf + ctxt->md5_i, input, gap);
+		md5_calc(ctxt->md5_buf, ctxt);
+
+		for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN)
+			md5_calc((uint8 *) (input + i), ctxt);
+
+		ctxt->md5_i = len - i;
+		memmove(ctxt->md5_buf, input + i, ctxt->md5_i);
+	}
+	else
+	{
+		memmove(ctxt->md5_buf + ctxt->md5_i, input, len);
+		ctxt->md5_i += len;
+	}
+}
+
+void
+md5_pad(md5_ctxt *ctxt)
+{
+	unsigned int gap;
+
+	/* Don't count up padding. Keep md5_n. */
+	gap = MD5_BUFLEN - ctxt->md5_i;
+	if (gap > 8)
+	{
+		memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat,
+				gap - sizeof(ctxt->md5_n));
+	}
+	else
+	{
+		/* including gap == 8 */
+		memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap);
+		md5_calc(ctxt->md5_buf, ctxt);
+		memmove(ctxt->md5_buf, md5_paddat + gap,
+				MD5_BUFLEN - sizeof(ctxt->md5_n));
+	}
+
+	/* 8 byte word */
+#ifndef WORDS_BIGENDIAN
+	memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8);
+#else
+	ctxt->md5_buf[56] = ctxt->md5_n8[7];
+	ctxt->md5_buf[57] = ctxt->md5_n8[6];
+	ctxt->md5_buf[58] = ctxt->md5_n8[5];
+	ctxt->md5_buf[59] = ctxt->md5_n8[4];
+	ctxt->md5_buf[60] = ctxt->md5_n8[3];
+	ctxt->md5_buf[61] = ctxt->md5_n8[2];
+	ctxt->md5_buf[62] = ctxt->md5_n8[1];
+	ctxt->md5_buf[63] = ctxt->md5_n8[0];
+#endif
+
+	md5_calc(ctxt->md5_buf, ctxt);
+}
+
+void
+md5_result(uint8 *digest, md5_ctxt *ctxt)
+{
+	/* 4 byte words */
+#ifndef WORDS_BIGENDIAN
+	memmove(digest, &ctxt->md5_st8[0], 16);
+#else
+	digest[0] = ctxt->md5_st8[3];
+	digest[1] = ctxt->md5_st8[2];
+	digest[2] = ctxt->md5_st8[1];
+	digest[3] = ctxt->md5_st8[0];
+	digest[4] = ctxt->md5_st8[7];
+	digest[5] = ctxt->md5_st8[6];
+	digest[6] = ctxt->md5_st8[5];
+	digest[7] = ctxt->md5_st8[4];
+	digest[8] = ctxt->md5_st8[11];
+	digest[9] = ctxt->md5_st8[10];
+	digest[10] = ctxt->md5_st8[9];
+	digest[11] = ctxt->md5_st8[8];
+	digest[12] = ctxt->md5_st8[15];
+	digest[13] = ctxt->md5_st8[14];
+	digest[14] = ctxt->md5_st8[13];
+	digest[15] = ctxt->md5_st8[12];
+#endif
+}
+
+#ifdef WORDS_BIGENDIAN
+static uint32 X[16];
+#endif
+
+static void
+md5_calc(uint8 *b64, md5_ctxt *ctxt)
+{
+	uint32		A = ctxt->md5_sta;
+	uint32		B = ctxt->md5_stb;
+	uint32		C = ctxt->md5_stc;
+	uint32		D = ctxt->md5_std;
+
+#ifndef WORDS_BIGENDIAN
+	uint32	   *X = (uint32 *) b64;
+#else
+	/* 4 byte words */
+	/* what a brute force but fast! */
+	uint8	   *y = (uint8 *) X;
+
+	y[0] = b64[3];
+	y[1] = b64[2];
+	y[2] = b64[1];
+	y[3] = b64[0];
+	y[4] = b64[7];
+	y[5] = b64[6];
+	y[6] = b64[5];
+	y[7] = b64[4];
+	y[8] = b64[11];
+	y[9] = b64[10];
+	y[10] = b64[9];
+	y[11] = b64[8];
+	y[12] = b64[15];
+	y[13] = b64[14];
+	y[14] = b64[13];
+	y[15] = b64[12];
+	y[16] = b64[19];
+	y[17] = b64[18];
+	y[18] = b64[17];
+	y[19] = b64[16];
+	y[20] = b64[23];
+	y[21] = b64[22];
+	y[22] = b64[21];
+	y[23] = b64[20];
+	y[24] = b64[27];
+	y[25] = b64[26];
+	y[26] = b64[25];
+	y[27] = b64[24];
+	y[28] = b64[31];
+	y[29] = b64[30];
+	y[30] = b64[29];
+	y[31] = b64[28];
+	y[32] = b64[35];
+	y[33] = b64[34];
+	y[34] = b64[33];
+	y[35] = b64[32];
+	y[36] = b64[39];
+	y[37] = b64[38];
+	y[38] = b64[37];
+	y[39] = b64[36];
+	y[40] = b64[43];
+	y[41] = b64[42];
+	y[42] = b64[41];
+	y[43] = b64[40];
+	y[44] = b64[47];
+	y[45] = b64[46];
+	y[46] = b64[45];
+	y[47] = b64[44];
+	y[48] = b64[51];
+	y[49] = b64[50];
+	y[50] = b64[49];
+	y[51] = b64[48];
+	y[52] = b64[55];
+	y[53] = b64[54];
+	y[54] = b64[53];
+	y[55] = b64[52];
+	y[56] = b64[59];
+	y[57] = b64[58];
+	y[58] = b64[57];
+	y[59] = b64[56];
+	y[60] = b64[63];
+	y[61] = b64[62];
+	y[62] = b64[61];
+	y[63] = b64[60];
+#endif
+
+	ROUND1(A, B, C, D, 0, Sa, 1);
+	ROUND1(D, A, B, C, 1, Sb, 2);
+	ROUND1(C, D, A, B, 2, Sc, 3);
+	ROUND1(B, C, D, A, 3, Sd, 4);
+	ROUND1(A, B, C, D, 4, Sa, 5);
+	ROUND1(D, A, B, C, 5, Sb, 6);
+	ROUND1(C, D, A, B, 6, Sc, 7);
+	ROUND1(B, C, D, A, 7, Sd, 8);
+	ROUND1(A, B, C, D, 8, Sa, 9);
+	ROUND1(D, A, B, C, 9, Sb, 10);
+	ROUND1(C, D, A, B, 10, Sc, 11);
+	ROUND1(B, C, D, A, 11, Sd, 12);
+	ROUND1(A, B, C, D, 12, Sa, 13);
+	ROUND1(D, A, B, C, 13, Sb, 14);
+	ROUND1(C, D, A, B, 14, Sc, 15);
+	ROUND1(B, C, D, A, 15, Sd, 16);
+
+	ROUND2(A, B, C, D, 1, Se, 17);
+	ROUND2(D, A, B, C, 6, Sf, 18);
+	ROUND2(C, D, A, B, 11, Sg, 19);
+	ROUND2(B, C, D, A, 0, Sh, 20);
+	ROUND2(A, B, C, D, 5, Se, 21);
+	ROUND2(D, A, B, C, 10, Sf, 22);
+	ROUND2(C, D, A, B, 15, Sg, 23);
+	ROUND2(B, C, D, A, 4, Sh, 24);
+	ROUND2(A, B, C, D, 9, Se, 25);
+	ROUND2(D, A, B, C, 14, Sf, 26);
+	ROUND2(C, D, A, B, 3, Sg, 27);
+	ROUND2(B, C, D, A, 8, Sh, 28);
+	ROUND2(A, B, C, D, 13, Se, 29);
+	ROUND2(D, A, B, C, 2, Sf, 30);
+	ROUND2(C, D, A, B, 7, Sg, 31);
+	ROUND2(B, C, D, A, 12, Sh, 32);
+
+	ROUND3(A, B, C, D, 5, Si, 33);
+	ROUND3(D, A, B, C, 8, Sj, 34);
+	ROUND3(C, D, A, B, 11, Sk, 35);
+	ROUND3(B, C, D, A, 14, Sl, 36);
+	ROUND3(A, B, C, D, 1, Si, 37);
+	ROUND3(D, A, B, C, 4, Sj, 38);
+	ROUND3(C, D, A, B, 7, Sk, 39);
+	ROUND3(B, C, D, A, 10, Sl, 40);
+	ROUND3(A, B, C, D, 13, Si, 41);
+	ROUND3(D, A, B, C, 0, Sj, 42);
+	ROUND3(C, D, A, B, 3, Sk, 43);
+	ROUND3(B, C, D, A, 6, Sl, 44);
+	ROUND3(A, B, C, D, 9, Si, 45);
+	ROUND3(D, A, B, C, 12, Sj, 46);
+	ROUND3(C, D, A, B, 15, Sk, 47);
+	ROUND3(B, C, D, A, 2, Sl, 48);
+
+	ROUND4(A, B, C, D, 0, Sm, 49);
+	ROUND4(D, A, B, C, 7, Sn, 50);
+	ROUND4(C, D, A, B, 14, So, 51);
+	ROUND4(B, C, D, A, 5, Sp, 52);
+	ROUND4(A, B, C, D, 12, Sm, 53);
+	ROUND4(D, A, B, C, 3, Sn, 54);
+	ROUND4(C, D, A, B, 10, So, 55);
+	ROUND4(B, C, D, A, 1, Sp, 56);
+	ROUND4(A, B, C, D, 8, Sm, 57);
+	ROUND4(D, A, B, C, 15, Sn, 58);
+	ROUND4(C, D, A, B, 6, So, 59);
+	ROUND4(B, C, D, A, 13, Sp, 60);
+	ROUND4(A, B, C, D, 4, Sm, 61);
+	ROUND4(D, A, B, C, 11, Sn, 62);
+	ROUND4(C, D, A, B, 2, So, 63);
+	ROUND4(B, C, D, A, 9, Sp, 64);
+
+	ctxt->md5_sta += A;
+	ctxt->md5_stb += B;
+	ctxt->md5_stc += C;
+	ctxt->md5_std += D;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/md5.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/md5.h b/contrib/pgcrypto/md5.h
new file mode 100644
index 0000000..03b9ab5
--- /dev/null
+++ b/contrib/pgcrypto/md5.h
@@ -0,0 +1,79 @@
+/*	contrib/pgcrypto/md5.h */
+/*	   $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $	   */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce 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 project nor the names of its contributors
+ *	  may be used to endorse or promote products derived from this software
+ *	  without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _NETINET6_MD5_H_
+#define _NETINET6_MD5_H_
+
+#define MD5_BUFLEN	64
+
+typedef struct
+{
+	union
+	{
+		uint32		md5_state32[4];
+		uint8		md5_state8[16];
+	}			md5_st;
+
+#define md5_sta		md5_st.md5_state32[0]
+#define md5_stb		md5_st.md5_state32[1]
+#define md5_stc		md5_st.md5_state32[2]
+#define md5_std		md5_st.md5_state32[3]
+#define md5_st8		md5_st.md5_state8
+
+	union
+	{
+		uint64		md5_count64;
+		uint8		md5_count8[8];
+	}			md5_count;
+#define md5_n	md5_count.md5_count64
+#define md5_n8	md5_count.md5_count8
+
+	unsigned int md5_i;
+	uint8		md5_buf[MD5_BUFLEN];
+} md5_ctxt;
+
+extern void md5_init(md5_ctxt *);
+extern void md5_loop(md5_ctxt *, const uint8 *, unsigned int);
+extern void md5_pad(md5_ctxt *);
+extern void md5_result(uint8 *, md5_ctxt *);
+
+/* compatibility */
+#define MD5_CTX		md5_ctxt
+#define MD5Init(x)	md5_init((x))
+#define MD5Update(x, y, z)	md5_loop((x), (y), (z))
+#define MD5Final(x, y) \
+do {				\
+	md5_pad((y));		\
+	md5_result((x), (y));	\
+} while (0)
+
+#endif   /* ! _NETINET6_MD5_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/openssl.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
new file mode 100644
index 0000000..ad7fb9e
--- /dev/null
+++ b/contrib/pgcrypto/openssl.c
@@ -0,0 +1,1032 @@
+/*
+ * openssl.c
+ *		Wrapper for OpenSSL library.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/openssl.c
+ */
+
+#include "postgres.h"
+
+#include "px.h"
+
+#include <openssl/evp.h>
+#include <openssl/blowfish.h>
+#include <openssl/cast.h>
+#include <openssl/des.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+/*
+ * Max lengths we might want to handle.
+ */
+#define MAX_KEY		(512/8)
+#define MAX_IV		(128/8)
+
+/*
+ * Compatibility with OpenSSL 0.9.6
+ *
+ * It needs AES and newer DES and digest API.
+ */
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+
+/*
+ * Nothing needed for OpenSSL 0.9.7+
+ */
+
+#include <openssl/aes.h>
+#else							/* old OPENSSL */
+
+/*
+ * Emulate OpenSSL AES.
+ */
+
+#include "rijndael.c"
+
+#define AES_ENCRYPT 1
+#define AES_DECRYPT 0
+#define AES_KEY		rijndael_ctx
+
+static int
+AES_set_encrypt_key(const uint8 *key, int kbits, AES_KEY *ctx)
+{
+	aes_set_key(ctx, key, kbits, 1);
+	return 0;
+}
+
+static int
+AES_set_decrypt_key(const uint8 *key, int kbits, AES_KEY *ctx)
+{
+	aes_set_key(ctx, key, kbits, 0);
+	return 0;
+}
+
+static void
+AES_ecb_encrypt(const uint8 *src, uint8 *dst, AES_KEY *ctx, int enc)
+{
+	memcpy(dst, src, 16);
+	if (enc)
+		aes_ecb_encrypt(ctx, dst, 16);
+	else
+		aes_ecb_decrypt(ctx, dst, 16);
+}
+
+static void
+AES_cbc_encrypt(const uint8 *src, uint8 *dst, int len, AES_KEY *ctx, uint8 *iv, int enc)
+{
+	memcpy(dst, src, len);
+	if (enc)
+	{
+		aes_cbc_encrypt(ctx, iv, dst, len);
+		memcpy(iv, dst + len - 16, 16);
+	}
+	else
+	{
+		aes_cbc_decrypt(ctx, iv, dst, len);
+		memcpy(iv, src + len - 16, 16);
+	}
+}
+
+/*
+ * Emulate DES_* API
+ */
+
+#define DES_key_schedule des_key_schedule
+#define DES_cblock des_cblock
+#define DES_set_key(k, ks) \
+		des_set_key((k), *(ks))
+#define DES_ecb_encrypt(i, o, k, e) \
+		des_ecb_encrypt((i), (o), *(k), (e))
+#define DES_ncbc_encrypt(i, o, l, k, iv, e) \
+		des_ncbc_encrypt((i), (o), (l), *(k), (iv), (e))
+#define DES_ecb3_encrypt(i, o, k1, k2, k3, e) \
+		des_ecb3_encrypt((des_cblock *)(i), (des_cblock *)(o), \
+				*(k1), *(k2), *(k3), (e))
+#define DES_ede3_cbc_encrypt(i, o, l, k1, k2, k3, iv, e) \
+		des_ede3_cbc_encrypt((i), (o), \
+				(l), *(k1), *(k2), *(k3), (iv), (e))
+
+/*
+ * Emulate newer digest API.
+ */
+
+static void
+EVP_MD_CTX_init(EVP_MD_CTX *ctx)
+{
+	memset(ctx, 0, sizeof(*ctx));
+}
+
+static int
+EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
+{
+	memset(ctx, 0, sizeof(*ctx));
+	return 1;
+}
+
+static int
+EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, void *engine)
+{
+	EVP_DigestInit(ctx, md);
+	return 1;
+}
+
+static int
+EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *res, unsigned int *len)
+{
+	EVP_DigestFinal(ctx, res, len);
+	return 1;
+}
+#endif   /* old OpenSSL */
+
+/*
+ * Provide SHA2 for older OpenSSL < 0.9.8
+ */
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+
+#include "sha2.c"
+#include "internal-sha2.c"
+
+typedef void (*init_f) (PX_MD *md);
+
+static int
+compat_find_digest(const char *name, PX_MD **res)
+{
+	init_f		init = NULL;
+
+	if (pg_strcasecmp(name, "sha224") == 0)
+		init = init_sha224;
+	else if (pg_strcasecmp(name, "sha256") == 0)
+		init = init_sha256;
+	else if (pg_strcasecmp(name, "sha384") == 0)
+		init = init_sha384;
+	else if (pg_strcasecmp(name, "sha512") == 0)
+		init = init_sha512;
+	else
+		return PXE_NO_HASH;
+
+	*res = px_alloc(sizeof(PX_MD));
+	init(*res);
+	return 0;
+}
+#else
+#define compat_find_digest(name, res)  (PXE_NO_HASH)
+#endif
+
+/*
+ * Hashes
+ */
+
+typedef struct OSSLDigest
+{
+	const EVP_MD *algo;
+	EVP_MD_CTX	ctx;
+} OSSLDigest;
+
+static unsigned
+digest_result_size(PX_MD *h)
+{
+	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+
+	return EVP_MD_CTX_size(&digest->ctx);
+}
+
+static unsigned
+digest_block_size(PX_MD *h)
+{
+	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+
+	return EVP_MD_CTX_block_size(&digest->ctx);
+}
+
+static void
+digest_reset(PX_MD *h)
+{
+	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+
+	EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL);
+}
+
+static void
+digest_update(PX_MD *h, const uint8 *data, unsigned dlen)
+{
+	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+
+	EVP_DigestUpdate(&digest->ctx, data, dlen);
+}
+
+static void
+digest_finish(PX_MD *h, uint8 *dst)
+{
+	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+
+	EVP_DigestFinal_ex(&digest->ctx, dst, NULL);
+}
+
+static void
+digest_free(PX_MD *h)
+{
+	OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
+
+	EVP_MD_CTX_cleanup(&digest->ctx);
+
+	px_free(digest);
+	px_free(h);
+}
+
+static int	px_openssl_initialized = 0;
+
+/* PUBLIC functions */
+
+int
+px_find_digest(const char *name, PX_MD **res)
+{
+	const EVP_MD *md;
+	PX_MD	   *h;
+	OSSLDigest *digest;
+
+	if (!px_openssl_initialized)
+	{
+		px_openssl_initialized = 1;
+		OpenSSL_add_all_algorithms();
+	}
+
+	md = EVP_get_digestbyname(name);
+	if (md == NULL)
+		return compat_find_digest(name, res);
+
+	digest = px_alloc(sizeof(*digest));
+	digest->algo = md;
+
+	EVP_MD_CTX_init(&digest->ctx);
+	if (EVP_DigestInit_ex(&digest->ctx, digest->algo, NULL) == 0)
+		return -1;
+
+	h = px_alloc(sizeof(*h));
+	h->result_size = digest_result_size;
+	h->block_size = digest_block_size;
+	h->reset = digest_reset;
+	h->update = digest_update;
+	h->finish = digest_finish;
+	h->free = digest_free;
+	h->p.ptr = (void *) digest;
+
+	*res = h;
+	return 0;
+}
+
+/*
+ * Ciphers
+ *
+ * The problem with OpenSSL is that the EVP* family
+ * of functions does not allow enough flexibility
+ * and forces some of the parameters (keylen,
+ * padding) to SSL defaults.
+ *
+ * So need to manage ciphers ourselves.
+ */
+
+struct ossl_cipher
+{
+	int			(*init) (PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv);
+	int			(*encrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
+	int			(*decrypt) (PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res);
+
+	int			block_size;
+	int			max_key_size;
+	int			stream_cipher;
+};
+
+typedef struct
+{
+	union
+	{
+		struct
+		{
+			BF_KEY		key;
+			int			num;
+		}			bf;
+		struct
+		{
+			DES_key_schedule key_schedule;
+		}			des;
+		struct
+		{
+			DES_key_schedule k1,
+						k2,
+						k3;
+		}			des3;
+		CAST_KEY	cast_key;
+		AES_KEY		aes_key;
+	}			u;
+	uint8		key[MAX_KEY];
+	uint8		iv[MAX_IV];
+	unsigned	klen;
+	unsigned	init;
+	const struct ossl_cipher *ciph;
+} ossldata;
+
+/* generic */
+
+static unsigned
+gen_ossl_block_size(PX_Cipher *c)
+{
+	ossldata   *od = (ossldata *) c->ptr;
+
+	return od->ciph->block_size;
+}
+
+static unsigned
+gen_ossl_key_size(PX_Cipher *c)
+{
+	ossldata   *od = (ossldata *) c->ptr;
+
+	return od->ciph->max_key_size;
+}
+
+static unsigned
+gen_ossl_iv_size(PX_Cipher *c)
+{
+	unsigned	ivlen;
+	ossldata   *od = (ossldata *) c->ptr;
+
+	ivlen = od->ciph->block_size;
+	return ivlen;
+}
+
+static void
+gen_ossl_free(PX_Cipher *c)
+{
+	ossldata   *od = (ossldata *) c->ptr;
+
+	memset(od, 0, sizeof(*od));
+	px_free(od);
+	px_free(c);
+}
+
+/* Blowfish */
+
+/*
+ * Check if strong crypto is supported. Some openssl installations
+ * support only short keys and unfortunately BF_set_key does not return any
+ * error value. This function tests if is possible to use strong key.
+ */
+static int
+bf_check_supported_key_len(void)
+{
+	static const uint8 key[56] = {
+		0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,
+		0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,
+		0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,
+		0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
+		0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	};
+
+	static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
+	static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};
+	static uint8 out[8];
+
+	BF_KEY		bf_key;
+
+	/* encrypt with 448bits key and verify output */
+	BF_set_key(&bf_key, 56, key);
+	BF_ecb_encrypt(data, out, &bf_key, BF_ENCRYPT);
+
+	if (memcmp(out, res, 8) != 0)
+		return 0;				/* Output does not match -> strong cipher is
+								 * not supported */
+	return 1;
+}
+
+static int
+bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
+{
+	ossldata   *od = c->ptr;
+	static int	bf_is_strong = -1;
+
+	/*
+	 * Test if key len is supported. BF_set_key silently cut large keys and it
+	 * could be be a problem when user transfer crypted data from one server
+	 * to another.
+	 */
+
+	if (bf_is_strong == -1)
+		bf_is_strong = bf_check_supported_key_len();
+
+	if (!bf_is_strong && klen > 16)
+		return PXE_KEY_TOO_BIG;
+
+	/* Key len is supported. We can use it. */
+	BF_set_key(&od->u.bf.key, klen, key);
+	if (iv)
+		memcpy(od->iv, iv, BF_BLOCK);
+	else
+		memset(od->iv, 0, BF_BLOCK);
+	od->u.bf.num = 0;
+	return 0;
+}
+
+static int
+bf_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	unsigned	i;
+	ossldata   *od = c->ptr;
+
+	for (i = 0; i < dlen / bs; i++)
+		BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_ENCRYPT);
+	return 0;
+}
+
+static int
+bf_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c),
+				i;
+	ossldata   *od = c->ptr;
+
+	for (i = 0; i < dlen / bs; i++)
+		BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_DECRYPT);
+	return 0;
+}
+
+static int
+bf_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_ENCRYPT);
+	return 0;
+}
+
+static int
+bf_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_DECRYPT);
+	return 0;
+}
+
+static int
+bf_cfb64_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv,
+					 &od->u.bf.num, BF_ENCRYPT);
+	return 0;
+}
+
+static int
+bf_cfb64_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv,
+					 &od->u.bf.num, BF_DECRYPT);
+	return 0;
+}
+
+/* DES */
+
+static int
+ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
+{
+	ossldata   *od = c->ptr;
+	DES_cblock	xkey;
+
+	memset(&xkey, 0, sizeof(xkey));
+	memcpy(&xkey, key, klen > 8 ? 8 : klen);
+	DES_set_key(&xkey, &od->u.des.key_schedule);
+	memset(&xkey, 0, sizeof(xkey));
+
+	if (iv)
+		memcpy(od->iv, iv, 8);
+	else
+		memset(od->iv, 0, 8);
+	return 0;
+}
+
+static int
+ossl_des_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	unsigned	i;
+	ossldata   *od = c->ptr;
+
+	for (i = 0; i < dlen / bs; i++)
+		DES_ecb_encrypt((DES_cblock *) (data + i * bs),
+						(DES_cblock *) (res + i * bs),
+						&od->u.des.key_schedule, 1);
+	return 0;
+}
+
+static int
+ossl_des_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	unsigned	i;
+	ossldata   *od = c->ptr;
+
+	for (i = 0; i < dlen / bs; i++)
+		DES_ecb_encrypt((DES_cblock *) (data + i * bs),
+						(DES_cblock *) (res + i * bs),
+						&od->u.des.key_schedule, 0);
+	return 0;
+}
+
+static int
+ossl_des_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	DES_ncbc_encrypt(data, res, dlen, &od->u.des.key_schedule,
+					 (DES_cblock *) od->iv, 1);
+	return 0;
+}
+
+static int
+ossl_des_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	DES_ncbc_encrypt(data, res, dlen, &od->u.des.key_schedule,
+					 (DES_cblock *) od->iv, 0);
+	return 0;
+}
+
+/* DES3 */
+
+static int
+ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
+{
+	ossldata   *od = c->ptr;
+	DES_cblock	xkey1,
+				xkey2,
+				xkey3;
+
+	memset(&xkey1, 0, sizeof(xkey1));
+	memset(&xkey2, 0, sizeof(xkey2));
+	memset(&xkey3, 0, sizeof(xkey3));
+	memcpy(&xkey1, key, klen > 8 ? 8 : klen);
+	if (klen > 8)
+		memcpy(&xkey2, key + 8, (klen - 8) > 8 ? 8 : (klen - 8));
+	if (klen > 16)
+		memcpy(&xkey3, key + 16, (klen - 16) > 8 ? 8 : (klen - 16));
+
+	DES_set_key(&xkey1, &od->u.des3.k1);
+	DES_set_key(&xkey2, &od->u.des3.k2);
+	DES_set_key(&xkey3, &od->u.des3.k3);
+	memset(&xkey1, 0, sizeof(xkey1));
+	memset(&xkey2, 0, sizeof(xkey2));
+	memset(&xkey3, 0, sizeof(xkey3));
+
+	if (iv)
+		memcpy(od->iv, iv, 8);
+	else
+		memset(od->iv, 0, 8);
+	return 0;
+}
+
+static int
+ossl_des3_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					  uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	unsigned	i;
+	ossldata   *od = c->ptr;
+
+	for (i = 0; i < dlen / bs; i++)
+		DES_ecb3_encrypt((void *) (data + i * bs), (void *) (res + i * bs),
+						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 1);
+	return 0;
+}
+
+static int
+ossl_des3_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					  uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	unsigned	i;
+	ossldata   *od = c->ptr;
+
+	for (i = 0; i < dlen / bs; i++)
+		DES_ecb3_encrypt((void *) (data + i * bs), (void *) (res + i * bs),
+						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3, 0);
+	return 0;
+}
+
+static int
+ossl_des3_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					  uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	DES_ede3_cbc_encrypt(data, res, dlen,
+						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
+						 (DES_cblock *) od->iv, 1);
+	return 0;
+}
+
+static int
+ossl_des3_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					  uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	DES_ede3_cbc_encrypt(data, res, dlen,
+						 &od->u.des3.k1, &od->u.des3.k2, &od->u.des3.k3,
+						 (DES_cblock *) od->iv, 0);
+	return 0;
+}
+
+/* CAST5 */
+
+static int
+ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
+{
+	ossldata   *od = c->ptr;
+	unsigned	bs = gen_ossl_block_size(c);
+
+	CAST_set_key(&od->u.cast_key, klen, key);
+	if (iv)
+		memcpy(od->iv, iv, bs);
+	else
+		memset(od->iv, 0, bs);
+	return 0;
+}
+
+static int
+ossl_cast_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	ossldata   *od = c->ptr;
+	const uint8 *end = data + dlen - bs;
+
+	for (; data <= end; data += bs, res += bs)
+		CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_ENCRYPT);
+	return 0;
+}
+
+static int
+ossl_cast_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	ossldata   *od = c->ptr;
+	const uint8 *end = data + dlen - bs;
+
+	for (; data <= end; data += bs, res += bs)
+		CAST_ecb_encrypt(data, res, &od->u.cast_key, CAST_DECRYPT);
+	return 0;
+}
+
+static int
+ossl_cast_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	CAST_cbc_encrypt(data, res, dlen, &od->u.cast_key, od->iv, CAST_ENCRYPT);
+	return 0;
+}
+
+static int
+ossl_cast_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
+{
+	ossldata   *od = c->ptr;
+
+	CAST_cbc_encrypt(data, res, dlen, &od->u.cast_key, od->iv, CAST_DECRYPT);
+	return 0;
+}
+
+/* AES */
+
+static int
+ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
+{
+	ossldata   *od = c->ptr;
+	unsigned	bs = gen_ossl_block_size(c);
+
+	if (klen <= 128 / 8)
+		od->klen = 128 / 8;
+	else if (klen <= 192 / 8)
+		od->klen = 192 / 8;
+	else if (klen <= 256 / 8)
+		od->klen = 256 / 8;
+	else
+		return PXE_KEY_TOO_BIG;
+
+	memcpy(od->key, key, klen);
+
+	if (iv)
+		memcpy(od->iv, iv, bs);
+	else
+		memset(od->iv, 0, bs);
+	return 0;
+}
+
+static int
+ossl_aes_key_init(ossldata *od, int type)
+{
+	int			err;
+
+	/*
+	 * Strong key support could be missing on some openssl installations. We
+	 * must check return value from set key function.
+	 */
+	if (type == AES_ENCRYPT)
+		err = AES_set_encrypt_key(od->key, od->klen * 8, &od->u.aes_key);
+	else
+		err = AES_set_decrypt_key(od->key, od->klen * 8, &od->u.aes_key);
+
+	if (err == 0)
+	{
+		od->init = 1;
+		return 0;
+	}
+	od->init = 0;
+	return PXE_KEY_TOO_BIG;
+}
+
+static int
+ossl_aes_ecb_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	ossldata   *od = c->ptr;
+	const uint8 *end = data + dlen - bs;
+	int			err;
+
+	if (!od->init)
+		if ((err = ossl_aes_key_init(od, AES_ENCRYPT)) != 0)
+			return err;
+
+	for (; data <= end; data += bs, res += bs)
+		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_ENCRYPT);
+	return 0;
+}
+
+static int
+ossl_aes_ecb_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	unsigned	bs = gen_ossl_block_size(c);
+	ossldata   *od = c->ptr;
+	const uint8 *end = data + dlen - bs;
+	int			err;
+
+	if (!od->init)
+		if ((err = ossl_aes_key_init(od, AES_DECRYPT)) != 0)
+			return err;
+
+	for (; data <= end; data += bs, res += bs)
+		AES_ecb_encrypt(data, res, &od->u.aes_key, AES_DECRYPT);
+	return 0;
+}
+
+static int
+ossl_aes_cbc_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	ossldata   *od = c->ptr;
+	int			err;
+
+	if (!od->init)
+		if ((err = ossl_aes_key_init(od, AES_ENCRYPT)) != 0)
+			return err;
+
+	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_ENCRYPT);
+	return 0;
+}
+
+static int
+ossl_aes_cbc_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen,
+					 uint8 *res)
+{
+	ossldata   *od = c->ptr;
+	int			err;
+
+	if (!od->init)
+		if ((err = ossl_aes_key_init(od, AES_DECRYPT)) != 0)
+			return err;
+
+	AES_cbc_encrypt(data, res, dlen, &od->u.aes_key, od->iv, AES_DECRYPT);
+	return 0;
+}
+
+/*
+ * aliases
+ */
+
+static PX_Alias ossl_aliases[] = {
+	{"bf", "bf-cbc"},
+	{"blowfish", "bf-cbc"},
+	{"blowfish-cbc", "bf-cbc"},
+	{"blowfish-ecb", "bf-ecb"},
+	{"blowfish-cfb", "bf-cfb"},
+	{"des", "des-cbc"},
+	{"3des", "des3-cbc"},
+	{"3des-ecb", "des3-ecb"},
+	{"3des-cbc", "des3-cbc"},
+	{"cast5", "cast5-cbc"},
+	{"aes", "aes-cbc"},
+	{"rijndael", "aes-cbc"},
+	{"rijndael-cbc", "aes-cbc"},
+	{"rijndael-ecb", "aes-ecb"},
+	{NULL}
+};
+
+static const struct ossl_cipher ossl_bf_cbc = {
+	bf_init, bf_cbc_encrypt, bf_cbc_decrypt,
+	64 / 8, 448 / 8, 0
+};
+
+static const struct ossl_cipher ossl_bf_ecb = {
+	bf_init, bf_ecb_encrypt, bf_ecb_decrypt,
+	64 / 8, 448 / 8, 0
+};
+
+static const struct ossl_cipher ossl_bf_cfb = {
+	bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt,
+	64 / 8, 448 / 8, 1
+};
+
+static const struct ossl_cipher ossl_des_ecb = {
+	ossl_des_init, ossl_des_ecb_encrypt, ossl_des_ecb_decrypt,
+	64 / 8, 64 / 8, 0
+};
+
+static const struct ossl_cipher ossl_des_cbc = {
+	ossl_des_init, ossl_des_cbc_encrypt, ossl_des_cbc_decrypt,
+	64 / 8, 64 / 8, 0
+};
+
+static const struct ossl_cipher ossl_des3_ecb = {
+	ossl_des3_init, ossl_des3_ecb_encrypt, ossl_des3_ecb_decrypt,
+	64 / 8, 192 / 8, 0
+};
+
+static const struct ossl_cipher ossl_des3_cbc = {
+	ossl_des3_init, ossl_des3_cbc_encrypt, ossl_des3_cbc_decrypt,
+	64 / 8, 192 / 8, 0
+};
+
+static const struct ossl_cipher ossl_cast_ecb = {
+	ossl_cast_init, ossl_cast_ecb_encrypt, ossl_cast_ecb_decrypt,
+	64 / 8, 128 / 8, 0
+};
+
+static const struct ossl_cipher ossl_cast_cbc = {
+	ossl_cast_init, ossl_cast_cbc_encrypt, ossl_cast_cbc_decrypt,
+	64 / 8, 128 / 8, 0
+};
+
+static const struct ossl_cipher ossl_aes_ecb = {
+	ossl_aes_init, ossl_aes_ecb_encrypt, ossl_aes_ecb_decrypt,
+	128 / 8, 256 / 8, 0
+};
+
+static const struct ossl_cipher ossl_aes_cbc = {
+	ossl_aes_init, ossl_aes_cbc_encrypt, ossl_aes_cbc_decrypt,
+	128 / 8, 256 / 8, 0
+};
+
+/*
+ * Special handlers
+ */
+struct ossl_cipher_lookup
+{
+	const char *name;
+	const struct ossl_cipher *ciph;
+};
+
+static const struct ossl_cipher_lookup ossl_cipher_types[] = {
+	{"bf-cbc", &ossl_bf_cbc},
+	{"bf-ecb", &ossl_bf_ecb},
+	{"bf-cfb", &ossl_bf_cfb},
+	{"des-ecb", &ossl_des_ecb},
+	{"des-cbc", &ossl_des_cbc},
+	{"des3-ecb", &ossl_des3_ecb},
+	{"des3-cbc", &ossl_des3_cbc},
+	{"cast5-ecb", &ossl_cast_ecb},
+	{"cast5-cbc", &ossl_cast_cbc},
+	{"aes-ecb", &ossl_aes_ecb},
+	{"aes-cbc", &ossl_aes_cbc},
+	{NULL}
+};
+
+/* PUBLIC functions */
+
+int
+px_find_cipher(const char *name, PX_Cipher **res)
+{
+	const struct ossl_cipher_lookup *i;
+	PX_Cipher  *c = NULL;
+	ossldata   *od;
+
+	name = px_resolve_alias(ossl_aliases, name);
+	for (i = ossl_cipher_types; i->name; i++)
+		if (strcmp(i->name, name) == 0)
+			break;
+	if (i->name == NULL)
+		return PXE_NO_CIPHER;
+
+	od = px_alloc(sizeof(*od));
+	memset(od, 0, sizeof(*od));
+	od->ciph = i->ciph;
+
+	c = px_alloc(sizeof(*c));
+	c->block_size = gen_ossl_block_size;
+	c->key_size = gen_ossl_key_size;
+	c->iv_size = gen_ossl_iv_size;
+	c->free = gen_ossl_free;
+	c->init = od->ciph->init;
+	c->encrypt = od->ciph->encrypt;
+	c->decrypt = od->ciph->decrypt;
+	c->ptr = od;
+
+	*res = c;
+	return 0;
+}
+
+
+static int	openssl_random_init = 0;
+
+/*
+ * OpenSSL random should re-feeded occasionally. From /dev/urandom
+ * preferably.
+ */
+static void
+init_openssl_rand(void)
+{
+	if (RAND_get_rand_method() == NULL)
+		RAND_set_rand_method(RAND_SSLeay());
+	openssl_random_init = 1;
+}
+
+int
+px_get_random_bytes(uint8 *dst, unsigned count)
+{
+	int			res;
+
+	if (!openssl_random_init)
+		init_openssl_rand();
+
+	res = RAND_bytes(dst, count);
+	if (res == 1)
+		return count;
+
+	return PXE_OSSL_RAND_ERROR;
+}
+
+int
+px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
+{
+	int			res;
+
+	if (!openssl_random_init)
+		init_openssl_rand();
+
+	res = RAND_pseudo_bytes(dst, count);
+	if (res == 0 || res == 1)
+		return count;
+
+	return PXE_OSSL_RAND_ERROR;
+}
+
+int
+px_add_entropy(const uint8 *data, unsigned count)
+{
+	/*
+	 * estimate 0 bits
+	 */
+	RAND_add(data, count, 0);
+	return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto--1.0.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgcrypto--1.0.sql b/contrib/pgcrypto/pgcrypto--1.0.sql
new file mode 100644
index 0000000..347825e
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto--1.0.sql
@@ -0,0 +1,202 @@
+/* contrib/pgcrypto/pgcrypto--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit
+
+CREATE FUNCTION digest(text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_digest'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION digest(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_digest'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION hmac(text, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_hmac'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION hmac(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_hmac'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION crypt(text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_crypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gen_salt(text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_gen_salt'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE FUNCTION gen_salt(text, int4)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_gen_salt_rounds'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE FUNCTION encrypt(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_encrypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION decrypt(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_decrypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION encrypt_iv(bytea, bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_encrypt_iv'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION decrypt_iv(bytea, bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_decrypt_iv'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gen_random_bytes(int4)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_random_bytes'
+LANGUAGE C VOLATILE STRICT;
+
+--
+-- pgp_sym_encrypt(data, key)
+--
+CREATE FUNCTION pgp_sym_encrypt(text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_sym_encrypt(data, key, args)
+--
+CREATE FUNCTION pgp_sym_encrypt(text, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_sym_decrypt(data, key)
+--
+CREATE FUNCTION pgp_sym_decrypt(bytea, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_sym_decrypt(data, key, args)
+--
+CREATE FUNCTION pgp_sym_decrypt(bytea, text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_encrypt(data, key)
+--
+CREATE FUNCTION pgp_pub_encrypt(text, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_pub_encrypt(data, key, args)
+--
+CREATE FUNCTION pgp_pub_encrypt(text, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_pub_decrypt(data, key)
+--
+CREATE FUNCTION pgp_pub_decrypt(bytea, bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_decrypt(data, key, psw)
+--
+CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_decrypt(data, key, psw, arg)
+--
+CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- PGP key ID
+--
+CREATE FUNCTION pgp_key_id(bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_key_id_w'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp armor
+--
+CREATE FUNCTION armor(bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_armor'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION dearmor(text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_dearmor'
+LANGUAGE C IMMUTABLE STRICT;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql b/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql
new file mode 100644
index 0000000..fe8d4c4
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql
@@ -0,0 +1,38 @@
+/* contrib/pgcrypto/pgcrypto--unpackaged--1.0.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit
+
+ALTER EXTENSION pgcrypto ADD function digest(text,text);
+ALTER EXTENSION pgcrypto ADD function digest(bytea,text);
+ALTER EXTENSION pgcrypto ADD function hmac(text,text,text);
+ALTER EXTENSION pgcrypto ADD function hmac(bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function crypt(text,text);
+ALTER EXTENSION pgcrypto ADD function gen_salt(text);
+ALTER EXTENSION pgcrypto ADD function gen_salt(text,integer);
+ALTER EXTENSION pgcrypto ADD function encrypt(bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function decrypt(bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function encrypt_iv(bytea,bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function decrypt_iv(bytea,bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function gen_random_bytes(integer);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt(text,text);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt_bytea(bytea,text);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt(text,text,text);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_encrypt_bytea(bytea,text,text);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt(bytea,text);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt_bytea(bytea,text);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt(bytea,text,text);
+ALTER EXTENSION pgcrypto ADD function pgp_sym_decrypt_bytea(bytea,text,text);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt(text,bytea);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt_bytea(bytea,bytea);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt(text,bytea,text);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_encrypt_bytea(bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt(bytea,bytea);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt_bytea(bytea,bytea);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt(bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt_bytea(bytea,bytea,text);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt(bytea,bytea,text,text);
+ALTER EXTENSION pgcrypto ADD function pgp_pub_decrypt_bytea(bytea,bytea,text,text);
+ALTER EXTENSION pgcrypto ADD function pgp_key_id(bytea);
+ALTER EXTENSION pgcrypto ADD function armor(bytea);
+ALTER EXTENSION pgcrypto ADD function dearmor(text);

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto.c
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
new file mode 100644
index 0000000..a441ca7
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -0,0 +1,469 @@
+/*
+ * pgcrypto.c
+ *		Various cryptographic stuff for PostgreSQL.
+ *
+ * Copyright (c) 2001 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgcrypto.c
+ */
+
+#include "postgres.h"
+
+#include <ctype.h>
+
+#include "parser/scansup.h"
+#include "utils/builtins.h"
+
+#include "px.h"
+#include "px-crypt.h"
+#include "pgcrypto.h"
+
+PG_MODULE_MAGIC;
+
+/* private stuff */
+
+typedef int (*PFN) (const char *name, void **res);
+static void *find_provider(text *name, PFN pf, char *desc, int silent);
+
+/* SQL function: hash(bytea, text) returns bytea */
+PG_FUNCTION_INFO_V1(pg_digest);
+
+Datum
+pg_digest(PG_FUNCTION_ARGS)
+{
+	bytea	   *arg;
+	text	   *name;
+	unsigned	len,
+				hlen;
+	PX_MD	   *md;
+	bytea	   *res;
+
+	name = PG_GETARG_TEXT_P(1);
+
+	/* will give error if fails */
+	md = find_provider(name, (PFN) px_find_digest, "Digest", 0);
+
+	hlen = px_md_result_size(md);
+
+	res = (text *) palloc(hlen + VARHDRSZ);
+	SET_VARSIZE(res, hlen + VARHDRSZ);
+
+	arg = PG_GETARG_BYTEA_P(0);
+	len = VARSIZE(arg) - VARHDRSZ;
+
+	px_md_update(md, (uint8 *) VARDATA(arg), len);
+	px_md_finish(md, (uint8 *) VARDATA(res));
+	px_md_free(md);
+
+	PG_FREE_IF_COPY(arg, 0);
+	PG_FREE_IF_COPY(name, 1);
+
+	PG_RETURN_BYTEA_P(res);
+}
+
+/* SQL function: hmac(data:bytea, key:bytea, type:text) returns bytea */
+PG_FUNCTION_INFO_V1(pg_hmac);
+
+Datum
+pg_hmac(PG_FUNCTION_ARGS)
+{
+	bytea	   *arg;
+	bytea	   *key;
+	text	   *name;
+	unsigned	len,
+				hlen,
+				klen;
+	PX_HMAC    *h;
+	bytea	   *res;
+
+	name = PG_GETARG_TEXT_P(2);
+
+	/* will give error if fails */
+	h = find_provider(name, (PFN) px_find_hmac, "HMAC", 0);
+
+	hlen = px_hmac_result_size(h);
+
+	res = (text *) palloc(hlen + VARHDRSZ);
+	SET_VARSIZE(res, hlen + VARHDRSZ);
+
+	arg = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	len = VARSIZE(arg) - VARHDRSZ;
+	klen = VARSIZE(key) - VARHDRSZ;
+
+	px_hmac_init(h, (uint8 *) VARDATA(key), klen);
+	px_hmac_update(h, (uint8 *) VARDATA(arg), len);
+	px_hmac_finish(h, (uint8 *) VARDATA(res));
+	px_hmac_free(h);
+
+	PG_FREE_IF_COPY(arg, 0);
+	PG_FREE_IF_COPY(key, 1);
+	PG_FREE_IF_COPY(name, 2);
+
+	PG_RETURN_BYTEA_P(res);
+}
+
+
+/* SQL function: pg_gen_salt(text) returns text */
+PG_FUNCTION_INFO_V1(pg_gen_salt);
+
+Datum
+pg_gen_salt(PG_FUNCTION_ARGS)
+{
+	text	   *arg0 = PG_GETARG_TEXT_PP(0);
+	int			len;
+	char		buf[PX_MAX_SALT_LEN + 1];
+
+	text_to_cstring_buffer(arg0, buf, sizeof(buf));
+	len = px_gen_salt(buf, buf, 0);
+	if (len < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("gen_salt: %s", px_strerror(len))));
+
+	PG_FREE_IF_COPY(arg0, 0);
+
+	PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len));
+}
+
+/* SQL function: pg_gen_salt(text, int4) returns text */
+PG_FUNCTION_INFO_V1(pg_gen_salt_rounds);
+
+Datum
+pg_gen_salt_rounds(PG_FUNCTION_ARGS)
+{
+	text	   *arg0 = PG_GETARG_TEXT_PP(0);
+	int			rounds = PG_GETARG_INT32(1);
+	int			len;
+	char		buf[PX_MAX_SALT_LEN + 1];
+
+	text_to_cstring_buffer(arg0, buf, sizeof(buf));
+	len = px_gen_salt(buf, buf, rounds);
+	if (len < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("gen_salt: %s", px_strerror(len))));
+
+	PG_FREE_IF_COPY(arg0, 0);
+
+	PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len));
+}
+
+/* SQL function: pg_crypt(psw:text, salt:text) returns text */
+PG_FUNCTION_INFO_V1(pg_crypt);
+
+Datum
+pg_crypt(PG_FUNCTION_ARGS)
+{
+	text	   *arg0 = PG_GETARG_TEXT_PP(0);
+	text	   *arg1 = PG_GETARG_TEXT_PP(1);
+	char	   *buf0,
+			   *buf1,
+			   *cres,
+			   *resbuf;
+	text	   *res;
+
+	buf0 = text_to_cstring(arg0);
+	buf1 = text_to_cstring(arg1);
+
+	resbuf = palloc0(PX_MAX_CRYPT);
+
+	cres = px_crypt(buf0, buf1, resbuf, PX_MAX_CRYPT);
+
+	pfree(buf0);
+	pfree(buf1);
+
+	if (cres == NULL)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("crypt(3) returned NULL")));
+
+	res = cstring_to_text(cres);
+
+	pfree(resbuf);
+
+	PG_FREE_IF_COPY(arg0, 0);
+	PG_FREE_IF_COPY(arg1, 1);
+
+	PG_RETURN_TEXT_P(res);
+}
+
+/* SQL function: pg_encrypt(bytea, bytea, text) returns bytea */
+PG_FUNCTION_INFO_V1(pg_encrypt);
+
+Datum
+pg_encrypt(PG_FUNCTION_ARGS)
+{
+	int			err;
+	bytea	   *data,
+			   *key,
+			   *res;
+	text	   *type;
+	PX_Combo   *c;
+	unsigned	dlen,
+				klen,
+				rlen;
+
+	type = PG_GETARG_TEXT_P(2);
+	c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	dlen = VARSIZE(data) - VARHDRSZ;
+	klen = VARSIZE(key) - VARHDRSZ;
+
+	rlen = px_combo_encrypt_len(c, dlen);
+	res = palloc(VARHDRSZ + rlen);
+
+	err = px_combo_init(c, (uint8 *) VARDATA(key), klen, NULL, 0);
+	if (!err)
+		err = px_combo_encrypt(c, (uint8 *) VARDATA(data), dlen,
+							   (uint8 *) VARDATA(res), &rlen);
+	px_combo_free(c);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	PG_FREE_IF_COPY(type, 2);
+
+	if (err)
+	{
+		pfree(res);
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("encrypt error: %s", px_strerror(err))));
+	}
+
+	SET_VARSIZE(res, VARHDRSZ + rlen);
+	PG_RETURN_BYTEA_P(res);
+}
+
+/* SQL function: pg_decrypt(bytea, bytea, text) returns bytea */
+PG_FUNCTION_INFO_V1(pg_decrypt);
+
+Datum
+pg_decrypt(PG_FUNCTION_ARGS)
+{
+	int			err;
+	bytea	   *data,
+			   *key,
+			   *res;
+	text	   *type;
+	PX_Combo   *c;
+	unsigned	dlen,
+				klen,
+				rlen;
+
+	type = PG_GETARG_TEXT_P(2);
+	c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	dlen = VARSIZE(data) - VARHDRSZ;
+	klen = VARSIZE(key) - VARHDRSZ;
+
+	rlen = px_combo_decrypt_len(c, dlen);
+	res = palloc(VARHDRSZ + rlen);
+
+	err = px_combo_init(c, (uint8 *) VARDATA(key), klen, NULL, 0);
+	if (!err)
+		err = px_combo_decrypt(c, (uint8 *) VARDATA(data), dlen,
+							   (uint8 *) VARDATA(res), &rlen);
+
+	px_combo_free(c);
+
+	if (err)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("decrypt error: %s", px_strerror(err))));
+
+	SET_VARSIZE(res, VARHDRSZ + rlen);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	PG_FREE_IF_COPY(type, 2);
+
+	PG_RETURN_BYTEA_P(res);
+}
+
+/* SQL function: pg_encrypt_iv(bytea, bytea, bytea, text) returns bytea */
+PG_FUNCTION_INFO_V1(pg_encrypt_iv);
+
+Datum
+pg_encrypt_iv(PG_FUNCTION_ARGS)
+{
+	int			err;
+	bytea	   *data,
+			   *key,
+			   *iv,
+			   *res;
+	text	   *type;
+	PX_Combo   *c;
+	unsigned	dlen,
+				klen,
+				ivlen,
+				rlen;
+
+	type = PG_GETARG_TEXT_P(3);
+	c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	iv = PG_GETARG_BYTEA_P(2);
+	dlen = VARSIZE(data) - VARHDRSZ;
+	klen = VARSIZE(key) - VARHDRSZ;
+	ivlen = VARSIZE(iv) - VARHDRSZ;
+
+	rlen = px_combo_encrypt_len(c, dlen);
+	res = palloc(VARHDRSZ + rlen);
+
+	err = px_combo_init(c, (uint8 *) VARDATA(key), klen,
+						(uint8 *) VARDATA(iv), ivlen);
+	if (!err)
+		err = px_combo_encrypt(c, (uint8 *) VARDATA(data), dlen,
+							   (uint8 *) VARDATA(res), &rlen);
+
+	px_combo_free(c);
+
+	if (err)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("encrypt_iv error: %s", px_strerror(err))));
+
+	SET_VARSIZE(res, VARHDRSZ + rlen);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	PG_FREE_IF_COPY(iv, 2);
+	PG_FREE_IF_COPY(type, 3);
+
+	PG_RETURN_BYTEA_P(res);
+}
+
+/* SQL function: pg_decrypt_iv(bytea, bytea, bytea, text) returns bytea */
+PG_FUNCTION_INFO_V1(pg_decrypt_iv);
+
+Datum
+pg_decrypt_iv(PG_FUNCTION_ARGS)
+{
+	int			err;
+	bytea	   *data,
+			   *key,
+			   *iv,
+			   *res;
+	text	   *type;
+	PX_Combo   *c;
+	unsigned	dlen,
+				klen,
+				rlen,
+				ivlen;
+
+	type = PG_GETARG_TEXT_P(3);
+	c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
+
+	data = PG_GETARG_BYTEA_P(0);
+	key = PG_GETARG_BYTEA_P(1);
+	iv = PG_GETARG_BYTEA_P(2);
+	dlen = VARSIZE(data) - VARHDRSZ;
+	klen = VARSIZE(key) - VARHDRSZ;
+	ivlen = VARSIZE(iv) - VARHDRSZ;
+
+	rlen = px_combo_decrypt_len(c, dlen);
+	res = palloc(VARHDRSZ + rlen);
+
+	err = px_combo_init(c, (uint8 *) VARDATA(key), klen,
+						(uint8 *) VARDATA(iv), ivlen);
+	if (!err)
+		err = px_combo_decrypt(c, (uint8 *) VARDATA(data), dlen,
+							   (uint8 *) VARDATA(res), &rlen);
+
+	px_combo_free(c);
+
+	if (err)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("decrypt_iv error: %s", px_strerror(err))));
+
+	SET_VARSIZE(res, VARHDRSZ + rlen);
+
+	PG_FREE_IF_COPY(data, 0);
+	PG_FREE_IF_COPY(key, 1);
+	PG_FREE_IF_COPY(iv, 2);
+	PG_FREE_IF_COPY(type, 3);
+
+	PG_RETURN_BYTEA_P(res);
+}
+
+/* SQL function: pg_random_bytes(int4) returns bytea */
+PG_FUNCTION_INFO_V1(pg_random_bytes);
+
+Datum
+pg_random_bytes(PG_FUNCTION_ARGS)
+{
+	int			err;
+	int			len = PG_GETARG_INT32(0);
+	bytea	   *res;
+
+	if (len < 1 || len > 1024)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("Length not in range")));
+
+	res = palloc(VARHDRSZ + len);
+	SET_VARSIZE(res, VARHDRSZ + len);
+
+	/* generate result */
+	err = px_get_random_bytes((uint8 *) VARDATA(res), len);
+	if (err < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("Random generator error: %s", px_strerror(err))));
+
+	PG_RETURN_BYTEA_P(res);
+}
+
+static void *
+find_provider(text *name,
+			  PFN provider_lookup,
+			  char *desc, int silent)
+{
+	void	   *res;
+	char	   *buf;
+	int			err;
+
+	buf = downcase_truncate_identifier(VARDATA(name),
+									   VARSIZE(name) - VARHDRSZ,
+									   false);
+
+	err = provider_lookup(buf, &res);
+
+	if (err && !silent)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("Cannot use \"%s\": %s", buf, px_strerror(err))));
+
+	pfree(buf);
+
+	return err ? NULL : res;
+}

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto.control
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgcrypto.control b/contrib/pgcrypto/pgcrypto.control
new file mode 100644
index 0000000..8375cf9
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto.control
@@ -0,0 +1,5 @@
+# pgcrypto extension
+comment = 'cryptographic functions'
+default_version = '1.0'
+module_pathname = '$libdir/pgcrypto'
+relocatable = true

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/pgcrypto.h
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/pgcrypto.h b/contrib/pgcrypto/pgcrypto.h
new file mode 100644
index 0000000..6284ba2
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto.h
@@ -0,0 +1,49 @@
+/*
+ * pgcrypto.h
+ *		Header file for pgcrypto.
+ *
+ * Copyright (c) 2000 Marko Kreen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *	  notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *	  notice, this list of conditions and the following disclaimer in the
+ *	  documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * contrib/pgcrypto/pgcrypto.h
+ */
+
+#ifndef _PG_CRYPTO_H
+#define _PG_CRYPTO_H
+
+#include "fmgr.h"
+
+/* exported functions */
+Datum		pg_digest(PG_FUNCTION_ARGS);
+Datum		pg_hmac(PG_FUNCTION_ARGS);
+Datum		pg_gen_salt(PG_FUNCTION_ARGS);
+Datum		pg_gen_salt_rounds(PG_FUNCTION_ARGS);
+Datum		pg_crypt(PG_FUNCTION_ARGS);
+Datum		pg_encrypt(PG_FUNCTION_ARGS);
+Datum		pg_decrypt(PG_FUNCTION_ARGS);
+Datum		pg_encrypt_iv(PG_FUNCTION_ARGS);
+Datum		pg_decrypt_iv(PG_FUNCTION_ARGS);
+Datum		pg_random_bytes(PG_FUNCTION_ARGS);
+
+#endif



[10/13] incubator-hawq git commit: HAWQ-1007. Add the pgcrypto code into hawq

Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/3des.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/3des.out b/contrib/pgcrypto/expected/3des.out
new file mode 100644
index 0000000..8983a73
--- /dev/null
+++ b/contrib/pgcrypto/expected/3des.out
@@ -0,0 +1,71 @@
+--
+-- 3DES cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- test vector from somewhere
+SELECT encode(encrypt(
+decode('80 00 00 00 00 00 00 00', 'hex'),
+decode('01 01 01 01 01 01 01 01
+	01 01 01 01 01 01 01 01
+	01 01 01 01 01 01 01 01', 'hex'),
+'3des-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 95f8a5e5dd31d900
+(1 row)
+
+-- val 95 F8 A5 E5 DD 31 D9 00
+select encode(	encrypt('', 'foo', '3des'), 'hex');
+      encode      
+------------------
+ 752111e37a2d7ac3
+(1 row)
+
+-- 10 bytes key
+select encode(	encrypt('foo', '0123456789', '3des'), 'hex');
+      encode      
+------------------
+ d2fb8baa1717cb02
+(1 row)
+
+-- 22 bytes key
+select encode(	encrypt('foo', '0123456789012345678901', '3des'), 'hex');
+      encode      
+------------------
+ a44360e699269817
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', '3des'), '0123456', '3des');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', '3des'), 'hex');
+      encode      
+------------------
+ 50735067b073bb93
+(1 row)
+
+select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', '3des');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789012345678901', '3des'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ b71e3422269d0ded19468f33d65cd663c28e0871984792a7b3ba0ddcecec8d2c
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '0123456789012345678901', '3des'), '0123456789012345678901', '3des');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/blowfish.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/blowfish.out b/contrib/pgcrypto/expected/blowfish.out
new file mode 100644
index 0000000..72557ea
--- /dev/null
+++ b/contrib/pgcrypto/expected/blowfish.out
@@ -0,0 +1,175 @@
+--
+-- Blowfish cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- some standard Blowfish testvalues
+SELECT encode(encrypt(
+decode('0000000000000000', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 4ef997456198dd78
+(1 row)
+
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('ffffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 51866fd5b85ecb8a
+(1 row)
+
+SELECT encode(encrypt(
+decode('1000000000000001', 'hex'),
+decode('3000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 7d856f9a613063f2
+(1 row)
+
+SELECT encode(encrypt(
+decode('1111111111111111', 'hex'),
+decode('1111111111111111', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 2466dd878b963c9d
+(1 row)
+
+SELECT encode(encrypt(
+decode('0123456789abcdef', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 0aceab0fc6a0a28d
+(1 row)
+
+SELECT encode(encrypt(
+decode('01a1d6d039776742', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 3273b8badc9e9e15
+(1 row)
+
+SELECT encode(encrypt(
+decode('ffffffffffffffff', 'hex'),
+decode('0000000000000000', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 014933e0cdaff6e4
+(1 row)
+
+-- setkey
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 93142887ee3be15c
+(1 row)
+
+-- with padding
+SELECT encode(encrypt(
+decode('01234567890123456789', 'hex'),
+decode('33443344334433443344334433443344', 'hex'),
+'bf-ecb'), 'hex');
+              encode              
+----------------------------------
+ 0d04a43a20456dee5ede6ed9e4dcaaa6
+(1 row)
+
+-- cbc
+-- 28 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f7220', 'hex'),
+'bf-cbc'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ 4f2beb748c4f689ec755edb9dc252a41b93a3786850b4c75d6a702b6a8e48825
+(1 row)
+
+-- 29 bytes key
+SELECT encode(encrypt(
+decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc', 'hex'),
+decode('37363534333231204e6f77206973207468652074696d6520666f722000', 'hex'),
+'bf-cbc'), 'hex');
+                                      encode                                      
+----------------------------------------------------------------------------------
+ 3ea6357a0ee7fad6d0c4b63464f2aafa40c2e91b4b7e1bba8114932fd92b5c8f111e7e50e7b2e541
+(1 row)
+
+-- blowfish-448
+SELECT encode(encrypt(
+decode('fedcba9876543210', 'hex'),
+decode('f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455667704689104c2fd3b2f584023641aba61761f1f1f1f0e0e0e0effffffffffffffff', 'hex'),
+'bf-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ c04504012e4e1f53
+(1 row)
+
+-- result: c04504012e4e1f53
+-- empty data
+select encode(encrypt('', 'foo', 'bf'), 'hex');
+      encode      
+------------------
+ 1871949bb2311c8e
+(1 row)
+
+-- 10 bytes key
+select encode(encrypt('foo', '0123456789', 'bf'), 'hex');
+      encode      
+------------------
+ 42f58af3b2c03f46
+(1 row)
+
+-- 22 bytes key
+select encode(encrypt('foo', '0123456789012345678901', 'bf'), 'hex');
+      encode      
+------------------
+ 86ab6f0bc72b5f22
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'bf'), '0123456', 'bf');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'bf'), 'hex');
+      encode      
+------------------
+ 95c7e89322525d59
+(1 row)
+
+select decrypt_iv(decode('95c7e89322525d59', 'hex'), '0123456', 'abcd', 'bf');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'bf'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ a76059f7a1b627b5b84080d9beb337714c7a7f8b70300023e5feb6dfa6813536
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'bf'), '0123456789', 'bf');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/cast5.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/cast5.out b/contrib/pgcrypto/expected/cast5.out
new file mode 100644
index 0000000..c1ecd91
--- /dev/null
+++ b/contrib/pgcrypto/expected/cast5.out
@@ -0,0 +1,88 @@
+--
+-- Cast5 cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- test vectors from RFC2144
+-- 128 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 238b4fe5847e44b2
+(1 row)
+
+-- result: 23 8B 4F E5 84 7E 44 B2
+-- 80 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12 34 56 78 23 45', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ eb6a711a2c02271b
+(1 row)
+
+-- result: EB 6A 71 1A 2C 02 27 1B
+-- 40 bit key
+SELECT encode(encrypt(
+decode('01 23 45 67 89 AB CD EF', 'hex'),
+decode('01 23 45 67 12', 'hex'),
+'cast5-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ 7ac816d16e9b302e
+(1 row)
+
+-- result: 7A C8 16 D1 6E 9B 30 2E
+-- cbc
+-- empty data
+select encode(	encrypt('', 'foo', 'cast5'), 'hex');
+      encode      
+------------------
+ a48bd1aabde4de10
+(1 row)
+
+-- 10 bytes key
+select encode(	encrypt('foo', '0123456789', 'cast5'), 'hex');
+      encode      
+------------------
+ b07f19255e60cb6d
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'cast5'), '0123456', 'cast5');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'cast5'), 'hex');
+      encode      
+------------------
+ 384a970695ce016a
+(1 row)
+
+select decrypt_iv(decode('384a970695ce016a', 'hex'),
+                '0123456', 'abcd', 'cast5');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'cast5'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ 04fcffc91533e1505dadcb10766d9fed0937818e663e402384e049942ba60fff
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'cast5'), '0123456789', 'cast5');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/crypt-blowfish.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/crypt-blowfish.out b/contrib/pgcrypto/expected/crypt-blowfish.out
new file mode 100644
index 0000000..329d78f
--- /dev/null
+++ b/contrib/pgcrypto/expected/crypt-blowfish.out
@@ -0,0 +1,27 @@
+--
+-- crypt() and gen_salt(): bcrypt
+--
+SELECT crypt('', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O');
+                            crypt                             
+--------------------------------------------------------------
+ $2a$06$RQiOJ.3ELirrXwxIZY8q0OlGbBEpDmx7IRZlNYvGJ1SHXwNi2cEKK
+(1 row)
+
+SELECT crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O');
+                            crypt                             
+--------------------------------------------------------------
+ $2a$06$RQiOJ.3ELirrXwxIZY8q0OR3CVJrAfda1z26CCHPnB6mmVZD8p0/C
+(1 row)
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+UPDATE ctest SET salt = gen_salt('bf', 8);
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+ worked 
+--------
+ t
+(1 row)
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/crypt-des.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/crypt-des.out b/contrib/pgcrypto/expected/crypt-des.out
new file mode 100644
index 0000000..b8b6050
--- /dev/null
+++ b/contrib/pgcrypto/expected/crypt-des.out
@@ -0,0 +1,27 @@
+--
+-- crypt() and gen_salt(): crypt-des
+--
+SELECT crypt('', 'NB');
+     crypt     
+---------------
+ NBPx/38Y48kHg
+(1 row)
+
+SELECT crypt('foox', 'NB');
+     crypt     
+---------------
+ NB53EGGqrrb5E
+(1 row)
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+UPDATE ctest SET salt = gen_salt('des');
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+ worked 
+--------
+ t
+(1 row)
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/crypt-md5.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/crypt-md5.out b/contrib/pgcrypto/expected/crypt-md5.out
new file mode 100644
index 0000000..a1c8304
--- /dev/null
+++ b/contrib/pgcrypto/expected/crypt-md5.out
@@ -0,0 +1,27 @@
+--
+-- crypt() and gen_salt(): md5
+--
+SELECT crypt('', '$1$Szzz0yzz');
+               crypt                
+------------------------------------
+ $1$Szzz0yzz$To38XrR3BsbXQW2ZpfKjF1
+(1 row)
+
+SELECT crypt('foox', '$1$Szzz0yzz');
+               crypt                
+------------------------------------
+ $1$Szzz0yzz$IYL49cd3t9bllsA7Jmz1M1
+(1 row)
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+UPDATE ctest SET salt = gen_salt('md5');
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+ worked 
+--------
+ t
+(1 row)
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/crypt-xdes.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/crypt-xdes.out b/contrib/pgcrypto/expected/crypt-xdes.out
new file mode 100644
index 0000000..cdcdefb
--- /dev/null
+++ b/contrib/pgcrypto/expected/crypt-xdes.out
@@ -0,0 +1,27 @@
+--
+-- crypt() and gen_salt(): extended des
+--
+SELECT crypt('', '_J9..j2zz');
+        crypt         
+----------------------
+ _J9..j2zzR/nIRDK3pPc
+(1 row)
+
+SELECT crypt('foox', '_J9..j2zz');
+        crypt         
+----------------------
+ _J9..j2zzAYKMvO2BYRY
+(1 row)
+
+CREATE TABLE ctest (data text, res text, salt text);
+INSERT INTO ctest VALUES ('password', '', '');
+UPDATE ctest SET salt = gen_salt('xdes', 1001);
+UPDATE ctest SET res = crypt(data, salt);
+SELECT res = crypt(data, res) AS "worked"
+FROM ctest;
+ worked 
+--------
+ t
+(1 row)
+
+DROP TABLE ctest;

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/des.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/des.out b/contrib/pgcrypto/expected/des.out
new file mode 100644
index 0000000..d0fd004
--- /dev/null
+++ b/contrib/pgcrypto/expected/des.out
@@ -0,0 +1,63 @@
+--
+-- DES cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- no official test vectors atm
+-- from blowfish.sql
+SELECT encode(encrypt(
+decode('0123456789abcdef', 'hex'),
+decode('fedcba9876543210', 'hex'),
+'des-ecb/pad:none'), 'hex');
+      encode      
+------------------
+ ed39d950fa74bcc4
+(1 row)
+
+-- empty data
+select encode(	encrypt('', 'foo', 'des'), 'hex');
+      encode      
+------------------
+ 752111e37a2d7ac3
+(1 row)
+
+-- 8 bytes key
+select encode(	encrypt('foo', '01234589', 'des'), 'hex');
+      encode      
+------------------
+ dec0f9c602b647a8
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'des'), '0123456', 'des');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'des'), 'hex');
+      encode      
+------------------
+ 50735067b073bb93
+(1 row)
+
+select decrypt_iv(decode('50735067b073bb93', 'hex'), '0123456', 'abcd', 'des');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '01234567', 'des'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ 5ad146043e5f30967e06a0fcbae602daf4ff2a5fd0ed12d6c5913cf85f1e36ca
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '01234567', 'des'), '01234567', 'des');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/hmac-md5.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/hmac-md5.out b/contrib/pgcrypto/expected/hmac-md5.out
new file mode 100644
index 0000000..9eded3b
--- /dev/null
+++ b/contrib/pgcrypto/expected/hmac-md5.out
@@ -0,0 +1,72 @@
+--
+-- HMAC-MD5
+--
+SELECT encode(hmac(
+'Hi There',
+decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
+'md5'), 'hex');
+              encode              
+----------------------------------
+ 9294727a3638bb1c13f48ef8158bfc9d
+(1 row)
+
+-- 2
+SELECT encode(hmac(
+'Jefe',
+'what do ya want for nothing?',
+'md5'), 'hex');
+              encode              
+----------------------------------
+ 813aead7c4a34bff01a16d61368e7c13
+(1 row)
+
+-- 3
+SELECT encode(hmac(
+decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'),
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'md5'), 'hex');
+              encode              
+----------------------------------
+ 56be34521d144c88dbb8c733f0e8b3f6
+(1 row)
+
+-- 4
+SELECT encode(hmac(
+decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'),
+decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'),
+'md5'), 'hex');
+              encode              
+----------------------------------
+ 697eaf0aca3a3aea3a75164746ffaa79
+(1 row)
+
+-- 5
+SELECT encode(hmac(
+'Test With Truncation',
+decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
+'md5'), 'hex');
+              encode              
+----------------------------------
+ 56461ef2342edc00f9bab995690efd4c
+(1 row)
+
+-- 6
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key - Hash Key First',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'md5'), 'hex');
+              encode              
+----------------------------------
+ 6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
+(1 row)
+
+-- 7
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'md5'), 'hex');
+              encode              
+----------------------------------
+ 6f630fad67cda0ee1fb1f562db3aa53e
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/hmac-sha1.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/hmac-sha1.out b/contrib/pgcrypto/expected/hmac-sha1.out
new file mode 100644
index 0000000..d5f1cf2
--- /dev/null
+++ b/contrib/pgcrypto/expected/hmac-sha1.out
@@ -0,0 +1,72 @@
+--
+-- HMAC-MD5
+--
+SELECT encode(hmac(
+'Hi There',
+decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'),
+'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 675b0b3a1b4ddf4e124872da6c2f632bfed957e9
+(1 row)
+
+-- 2
+SELECT encode(hmac(
+'Jefe',
+'what do ya want for nothing?',
+'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 156d4c35468a0339f3fa57a067bf47f814eb7a57
+(1 row)
+
+-- 3
+SELECT encode(hmac(
+decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'),
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ d730594d167e35d5956fd8003d0db3d3f46dc7bb
+(1 row)
+
+-- 4
+SELECT encode(hmac(
+decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'),
+decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'),
+'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 4c9007f4026250c6bc8414f9bf50c86c2d7235da
+(1 row)
+
+-- 5
+SELECT encode(hmac(
+'Test With Truncation',
+decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'),
+'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 37268b7e21e84da5720c53c4ba03ad1104039fa7
+(1 row)
+
+-- 6
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key - Hash Key First',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ aa4ae5e15272d00e95705637ce8a3b55ed402112
+(1 row)
+
+-- 7
+SELECT encode(hmac(
+'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data',
+decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'),
+'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ e8e99d0f45237d786d6bbaa7965c7808bbff1a91
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/init.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/init.out b/contrib/pgcrypto/expected/init.out
new file mode 100644
index 0000000..bd8f8e1
--- /dev/null
+++ b/contrib/pgcrypto/expected/init.out
@@ -0,0 +1,28 @@
+--
+-- init pgcrypto
+--
+CREATE EXTENSION pgcrypto;
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- check for encoding fn's
+SELECT encode('foo', 'hex');
+ encode 
+--------
+ 666f6f
+(1 row)
+
+SELECT decode('666f6f', 'hex');
+ decode 
+--------
+ foo
+(1 row)
+
+-- check error handling
+select gen_salt('foo');
+ERROR:  gen_salt: Unknown salt algorithm
+select digest('foo', 'foo');
+ERROR:  Cannot use "foo": No such hash algorithm
+select hmac('foo', 'foo', 'foo');
+ERROR:  Cannot use "foo": No such hash algorithm
+select encrypt('foo', 'foo', 'foo');
+ERROR:  Cannot use "foo": No such cipher algorithm

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/md5.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/md5.out b/contrib/pgcrypto/expected/md5.out
new file mode 100644
index 0000000..e3301af
--- /dev/null
+++ b/contrib/pgcrypto/expected/md5.out
@@ -0,0 +1,45 @@
+--
+-- MD5 message digest
+--
+SELECT encode(digest('', 'md5'), 'hex');
+              encode              
+----------------------------------
+ d41d8cd98f00b204e9800998ecf8427e
+(1 row)
+
+SELECT encode(digest('a', 'md5'), 'hex');
+              encode              
+----------------------------------
+ 0cc175b9c0f1b6a831c399e269772661
+(1 row)
+
+SELECT encode(digest('abc', 'md5'), 'hex');
+              encode              
+----------------------------------
+ 900150983cd24fb0d6963f7d28e17f72
+(1 row)
+
+SELECT encode(digest('message digest', 'md5'), 'hex');
+              encode              
+----------------------------------
+ f96b697d7cb7938d525a2f31aaf161d0
+(1 row)
+
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyz', 'md5'), 'hex');
+              encode              
+----------------------------------
+ c3fcd3d76192e4007dfb496cca67e13b
+(1 row)
+
+SELECT encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'md5'), 'hex');
+              encode              
+----------------------------------
+ d174ab98d277d9f5a5611c2c9f419d9f
+(1 row)
+
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'md5'), 'hex');
+              encode              
+----------------------------------
+ 57edf4a22be3c955ac49da2e2107b67a
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-armor.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-armor.out b/contrib/pgcrypto/expected/pgp-armor.out
new file mode 100644
index 0000000..c955494
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-armor.out
@@ -0,0 +1,104 @@
+--
+-- PGP Armor
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+select armor('');
+            armor            
+-----------------------------
+ -----BEGIN PGP MESSAGE-----+
+                            +
+ =twTO                      +
+ -----END PGP MESSAGE-----  +
+ 
+(1 row)
+
+select armor('test');
+            armor            
+-----------------------------
+ -----BEGIN PGP MESSAGE-----+
+                            +
+ dGVzdA==                   +
+ =+G7Q                      +
+ -----END PGP MESSAGE-----  +
+ 
+(1 row)
+
+select dearmor(armor(''));
+ dearmor 
+---------
+ 
+(1 row)
+
+select dearmor(armor('zooka'));
+ dearmor 
+---------
+ zooka
+(1 row)
+
+select armor('0123456789abcdef0123456789abcdef0123456789abcdef
+0123456789abcdef0123456789abcdef0123456789abcdef');
+                                    armor                                     
+------------------------------------------------------------------------------
+ -----BEGIN PGP MESSAGE-----                                                 +
+                                                                             +
+ MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmCjAxMjM0NTY3+
+ ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZg==                    +
+ =JFw5                                                                       +
+ -----END PGP MESSAGE-----                                                   +
+ 
+(1 row)
+
+-- lots formatting
+select dearmor(' a pgp msg:
+
+-----BEGIN PGP MESSAGE-----
+Comment: Some junk
+
+em9va2E=
+
+  =D5cR
+
+-----END PGP MESSAGE-----');
+ dearmor 
+---------
+ zooka
+(1 row)
+
+-- lots messages
+select dearmor('
+wrong packet:
+  -----BEGIN PGP MESSAGE-----
+
+  d3Jvbmc=
+  =vCYP
+  -----END PGP MESSAGE-----
+
+right packet:
+-----BEGIN PGP MESSAGE-----
+
+cmlnaHQ=
+=nbpj
+-----END PGP MESSAGE-----
+
+use only first packet
+-----BEGIN PGP MESSAGE-----
+
+d3Jvbmc=
+=vCYP
+-----END PGP MESSAGE-----
+');
+ dearmor 
+---------
+ right
+(1 row)
+
+-- bad crc
+select dearmor('
+-----BEGIN PGP MESSAGE-----
+
+em9va2E=
+=ZZZZ
+-----END PGP MESSAGE-----
+');
+ERROR:  Corrupt ascii-armor

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-compression.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-compression.out b/contrib/pgcrypto/expected/pgp-compression.out
new file mode 100644
index 0000000..32b350b
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-compression.out
@@ -0,0 +1,50 @@
+--
+-- PGP compression support
+--
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+
+ww0ECQMCsci6AdHnELlh0kQB4jFcVwHMJg0Bulop7m3Mi36s15TAhBo0AnzIrRFrdLVCkKohsS6+
+DMcmR53SXfLoDJOv/M8uKj3QSq7oWNIp95pxfA==
+=tbSn
+-----END PGP MESSAGE-----
+'), 'key', 'expect-compress-algo=1');
+ pgp_sym_decrypt 
+-----------------
+ Secret message
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=0'),
+	'key', 'expect-compress-algo=0');
+ pgp_sym_decrypt 
+-----------------
+ Secret message
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=1'),
+	'key', 'expect-compress-algo=1');
+ pgp_sym_decrypt 
+-----------------
+ Secret message
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key', 'compress-algo=2'),
+	'key', 'expect-compress-algo=2');
+ pgp_sym_decrypt 
+-----------------
+ Secret message
+(1 row)
+
+-- level=0 should turn compression off
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret message', 'key',
+			'compress-algo=2, compress-level=0'),
+	'key', 'expect-compress-algo=0');
+ pgp_sym_decrypt 
+-----------------
+ Secret message
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-decrypt.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-decrypt.out b/contrib/pgcrypto/expected/pgp-decrypt.out
new file mode 100644
index 0000000..859f4d6
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-decrypt.out
@@ -0,0 +1,366 @@
+--
+-- pgp_descrypt tests
+--
+--  Checking ciphers
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.blowfish.sha1.mdc.s2k3.z0
+
+jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS
+yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE=
+=JcP+
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCci97v0Q6Z0Zg0kQBsVf5Oe3iC+FBzUmuMV9KxmAyOMyjCc/5i8f1Eest
+UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA==
+=XtrP
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k3.z0
+
+jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI
+5FPTqAhIB2/2fjY8QEIs1ai00qphjX2NitxV/3Wn+6dufB4Q4g==
+=rCZt
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k3.z0
+
+jA0ECQMC4f/5djqCC1Rg0kQBTHEPsD+Sw7biBsM2er3vKyGPAQkuTBGKC5ie7hT/
+lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog==
+=fB6S
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking MDC modes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.nomdc.s2k3.z0
+
+jA0EBwMCnv07rlXqWctgyS2Dm2JfOKCRL4sLSLJUC8RS2cH7cIhKSuLitOtyquB+
+u9YkgfJfsuRJmgQ9tmo=
+=60ui
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE
+8Ex1Dsdt5UPvOz8W8VKQRS6loOfOe+yyXil8W3IYFwUpdDUi+Q==
+=moGf
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking hashes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.md5.mdc.s2k3.z0
+
+jA0EBwMClrXXtOXetohg0kQBn0Kl1ymevQZRHkdoYRHgzCwSQEiss7zYff2UNzgO
+KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA==
+=NyLk
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m
+/PM8jhgI5vxFYfNQjLl8y3fHYIomk9YflN9K/Q13iq8A8sjeTw==
+=FxbQ
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking S2K modes
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k0.z0
+
+jAQEBwAC0kQBKTaLAKE3xzps+QIZowqRNb2eAdzBw2LxEW2YD5PgNlbhJdGg+dvw
+Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw==
+=YvkV
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k1.z0
+
+jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK
+4IaWXVKEj9R2Lr2xntWWMGZtcKtjD2lFFRXXd9dZp1ZThNDz
+=dbXm
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCEq4Su3ZqNEJg0kQB4QG5jBTKF0i04xtH+avzmLhstBNRxvV3nsmB3cwl
+z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg==
+=VJKg
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k0.z0
+
+jAQECAAC0kQBBDnQWkgsx9YFaqDfWmpsiyAJ6y2xG/sBvap1dySYEMuZ+wJTXQ9E
+Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw==
+=cg+i
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k1.z0
+
+jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9
+7h8uZ2u9uRBOv222fZodGvc6bvq/4R4hAa/6qSHtm8mdmvGt
+=aHmC
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes192.sha1.mdc.s2k3.z0
+
+jA0ECAMCjFn6SRi3SONg0kQBqtSHPaD0m7rXfDAhCWU/ypAsI93GuHGRyM99cvMv
+q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw==
+=K0LS
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k0.z0
+
+jAQECQAC0kQB4L1eMbani07XF2ZYiXNK9LW3v8w41oUPl7dStmrJPQFwsdxmrDHu
+rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w==
+=RGts
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k1.z0
+
+jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO
++KVJW0qhk0An+Y2KF99/bYFl9cL5D3Tl43fC8fXGl3x3m7pR
+=SUrU
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes256.sha1.mdc.s2k3.z0
+
+jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+
+4+NRzL7cMW2RLAFnJbiqXDlRHMwleeuLN1up2WIxsxtYYuaBjA==
+=XZrG
+-----END PGP MESSAGE-----
+'), 'foobar');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking longer passwords
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCx6dBiuqrYNRg0kQBEo63AvA1SCslxP7ayanLf1H0/hlk2nONVhTwVEWi
+tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw==
+=XKKG
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCBDvYuS990iFg0kQBW31UK5OiCjWf5x6KJ8qNNT2HZWQCjCBZMU0XsOC6
+CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg==
+=gWDh
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+select pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCqXbFafC+ofVg0kQBejyiPqH0QMERVGfmPOjtAxvyG5KDIJPYojTgVSDt
+FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q==
+=OxOF
+-----END PGP MESSAGE-----
+'), 'x');
+ pgp_sym_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+-- Checking various data
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat1.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCGJ+SpuOysINg0kQBJfSjzsW0x4OVcAyr17O7FBvMTwIGeGcJd99oTQU8
+Xtx3kDqnhUq9Z1fS3qPbi5iNP2A9NxOBxPWz2JzxhydANlgbxg==
+=W/ik
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 0225e3ede6f2587b076d021a189ff60aad67e066
+(1 row)
+
+-- expected: 0225e3ede6f2587b076d021a189ff60aad67e066
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat2.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCvdpDvidNzMxg0jUBvj8eS2+1t/9/zgemxvhtc0fvdKGGbjH7dleaTJRB
+SaV9L04ky1qECNDx3XjnoKLC+H7IOQ==
+=Fxen
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ da39a3ee5e6b4b0d3255bfef95601890afd80709
+(1 row)
+
+-- expected: da39a3ee5e6b4b0d3255bfef95601890afd80709
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: dat3.aes.sha1.mdc.s2k3.z0
+
+jA0EBwMCxQvxJZ3G/HRg0lgBeYmTa7/uDAjPyFwSX4CYBgpZWVn/JS8JzILrcWF8
+gFnkUKIE0PSaYFp+Yi1VlRfUtRQ/X/LYNGa7tWZS+4VQajz2Xtz4vUeAEiYFYPXk
+73Hb8m1yRhQK
+=ivrD
+-----END PGP MESSAGE-----
+'), '0123456789abcdefghij'), 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
+(1 row)
+
+-- expected: 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c
+-- Checking CRLF
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: crlf mess
+
+ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
+a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
+=mBP9
+-----END PGP MESSAGE-----
+'), 'key', 'convert-crlf=0'), 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 9353062be7720f1446d30b9e75573a4833886784
+(1 row)
+
+-- expected: 9353062be7720f1446d30b9e75573a4833886784
+select encode(digest(pgp_sym_decrypt(dearmor('
+-----BEGIN PGP MESSAGE-----
+Comment: crlf mess
+
+ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms
+a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs
+=mBP9
+-----END PGP MESSAGE-----
+'), 'key', 'convert-crlf=1'), 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 7efefcab38467f7484d6fa43dc86cf5281bd78e2
+(1 row)
+
+-- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-encrypt-DISABLED.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-encrypt-DISABLED.out b/contrib/pgcrypto/expected/pgp-encrypt-DISABLED.out
new file mode 100644
index 0000000..4122300
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-encrypt-DISABLED.out
@@ -0,0 +1 @@
+-- no random source

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-encrypt.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-encrypt.out b/contrib/pgcrypto/expected/pgp-encrypt.out
new file mode 100644
index 0000000..8ef3875
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-encrypt.out
@@ -0,0 +1,191 @@
+--
+-- PGP encrypt
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- check whether the defaults are ok
+select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
+ 	'key', 'expect-cipher-algo=aes128,
+		expect-disable-mdc=0,
+		expect-sess-key=0,
+		expect-s2k-mode=3,
+		expect-s2k-digest-algo=sha1,
+		expect-compress-algo=0
+		');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- maybe the expect- stuff simply does not work
+select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'),
+ 	'key', 'expect-cipher-algo=bf,
+		expect-disable-mdc=1,
+		expect-sess-key=1,
+		expect-s2k-mode=0,
+		expect-s2k-digest-algo=md5,
+		expect-compress-algo=1
+		');
+NOTICE:  pgp_decrypt: unexpected cipher_algo: expected 4 got 7
+NOTICE:  pgp_decrypt: unexpected s2k_mode: expected 0 got 3
+NOTICE:  pgp_decrypt: unexpected s2k_digest_algo: expected 1 got 2
+NOTICE:  pgp_decrypt: unexpected use_sess_key: expected 1 got 0
+NOTICE:  pgp_decrypt: unexpected disable_mdc: expected 1 got 0
+NOTICE:  pgp_decrypt: unexpected compress_algo: expected 1 got 0
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- bytea as text
+select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz');
+ERROR:  Not text data
+-- text as bytea
+select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz');
+ pgp_sym_decrypt_bytea 
+-----------------------
+ Text
+(1 row)
+
+-- algorithm change
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'),
+ 	'key', 'expect-cipher-algo=bf');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'),
+ 	'key', 'expect-cipher-algo=aes128');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'),
+ 	'key', 'expect-cipher-algo=aes192');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- s2k change
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'),
+ 	'key', 'expect-s2k-mode=0');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'),
+ 	'key', 'expect-s2k-mode=1');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'),
+ 	'key', 'expect-s2k-mode=3');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- s2k digest change
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'),
+ 	'key', 'expect-s2k-digest-algo=md5');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+		pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'),
+ 	'key', 'expect-s2k-digest-algo=sha1');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- sess key
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'),
+ 	'key', 'expect-sess-key=0');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'),
+ 	'key', 'expect-sess-key=1');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'),
+ 	'key', 'expect-sess-key=1, expect-cipher-algo=bf');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'),
+ 	'key', 'expect-sess-key=1, expect-cipher-algo=aes192');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+select pgp_sym_decrypt(
+	pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'),
+ 	'key', 'expect-sess-key=1, expect-cipher-algo=aes256');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- no mdc
+select pgp_sym_decrypt(
+		pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'),
+ 	'key', 'expect-disable-mdc=1');
+ pgp_sym_decrypt 
+-----------------
+ Secret.
+(1 row)
+
+-- crlf
+select encode(pgp_sym_decrypt_bytea(
+	pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'),
+ 	'key'), 'hex');
+        encode        
+----------------------
+ 310d0a320d0a330d0d0a
+(1 row)
+
+-- conversion should be lossless
+select encode(digest(pgp_sym_decrypt(
+  pgp_sym_encrypt(E'\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'),
+ 	'key', 'convert-crlf=1'), 'sha1'), 'hex') as result,
+  encode(digest(E'\r\n0\n1\r\r\n\n2\r', 'sha1'), 'hex') as expect;
+                  result                  |                  expect                  
+------------------------------------------+------------------------------------------
+ 47bde5d88d6ef8770572b9cbb4278b402aa69966 | 47bde5d88d6ef8770572b9cbb4278b402aa69966
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-info.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-info.out b/contrib/pgcrypto/expected/pgp-info.out
new file mode 100644
index 0000000..1fe0088
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-info.out
@@ -0,0 +1,78 @@
+--
+-- PGP info functions
+--
+-- pgp_key_id
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=1;
+    pgp_key_id    
+------------------
+ D936CF64BB73F466
+(1 row)
+
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=2;
+    pgp_key_id    
+------------------
+ 2C226E1FFE5CC7D4
+(1 row)
+
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=3;
+    pgp_key_id    
+------------------
+ B68504FD128E1FF9
+(1 row)
+
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail
+ERROR:  No encryption key found
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=5;
+    pgp_key_id    
+------------------
+ D936CF64BB73F466
+(1 row)
+
+select pgp_key_id(dearmor(pubkey)) from keytbl where id=6;
+    pgp_key_id    
+------------------
+ FD0206C409B74875
+(1 row)
+
+select pgp_key_id(dearmor(seckey)) from keytbl where id=1;
+    pgp_key_id    
+------------------
+ D936CF64BB73F466
+(1 row)
+
+select pgp_key_id(dearmor(seckey)) from keytbl where id=2;
+    pgp_key_id    
+------------------
+ 2C226E1FFE5CC7D4
+(1 row)
+
+select pgp_key_id(dearmor(seckey)) from keytbl where id=3;
+    pgp_key_id    
+------------------
+ B68504FD128E1FF9
+(1 row)
+
+select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail
+ERROR:  No encryption key found
+select pgp_key_id(dearmor(seckey)) from keytbl where id=5;
+    pgp_key_id    
+------------------
+ D936CF64BB73F466
+(1 row)
+
+select pgp_key_id(dearmor(seckey)) from keytbl where id=6;
+    pgp_key_id    
+------------------
+ FD0206C409B74875
+(1 row)
+
+select pgp_key_id(dearmor(data)) as data_key_id
+from encdata order by id;
+   data_key_id    
+------------------
+ D936CF64BB73F466
+ 2C226E1FFE5CC7D4
+ B68504FD128E1FF9
+ FD0206C409B74875
+(4 rows)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-pubkey-DISABLED.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-pubkey-DISABLED.out b/contrib/pgcrypto/expected/pgp-pubkey-DISABLED.out
new file mode 100644
index 0000000..d35c097
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-pubkey-DISABLED.out
@@ -0,0 +1 @@
+-- no bignum support

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out b/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
new file mode 100644
index 0000000..7fbbd83
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out
@@ -0,0 +1,555 @@
+--
+-- PGP Public Key Encryption
+--
+-- As most of the low-level stuff is tested in symmetric key
+-- tests, here's only public-key specific tests
+create table keytbl (
+	id int4,
+	name text,
+	pubkey text,
+	seckey text
+);
+create table encdata (
+	id int4,
+	data text
+);
+insert into keytbl (id, name, pubkey, seckey)
+values (1, 'elg1024', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
+MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
+AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
+ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
+sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
++h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
+6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
+k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
+iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
+ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
+=RWci
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQAAAnj4i4st+s+C6
+WKTIDcL1Iy0Saq8lCp60H0VsZ2FtYWwgMTAyNCA8dGVzdEBleGFtcGxlLm9yZz6I
+XgQTEQIAHgUCQsghSAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAcKbwNGBdz
+ZDrbAJ9cp6AsjOhiLxwznsMJheGf4xkH8wCfUPjMCLm4tAEnyYn2hDNt7CB8B6Kd
+ATEEQsghShAEAIeUjW2yTALCfrEG3FhM3ZLvAHWAec2O0Mn/RDr59IN/W8wDYcZp
+m+oG0ZUDdIqMppQ8K2kylAH7gmYDXIP9D7MRRm/Zw3L4yFfKnVaZ6tT7szBbgW5h
+iOsHoOz49NXZT4jtMLdZS1/krm5Lam2MSPod9XN0Q2asY/igIMUfGDRjAAMGA/sE
+LNh3tWefqeDkoDBEYjcxdGnGVGJnNHvv/eoHy9H7dyD/kkhaOoRAa5ClYWSqD0kk
+a+SqTWhKG4XcbJyo1GsP6sqGhXDTM2+LBZPMKuVJQpEfoe9ruob/BbpXglfEiVE9
+VNiY7ZVyUdj3svYn4fK2X7ue1G3cHR2tL4lnOA4pYQAA9030E4u2ZKOfJBpUM+EM
+m9VmsGjaQZV4teB0R/q3W8sRIYhJBBgRAgAJBQJCyCFKAhsMAAoJEBwpvA0YF3Nk
+7a8AniFFotw1x2X+oryu3Q3nNtmxoKHpAJ9HU7jw7ydg33dI9J8gVkrmsSZ2/w==
+=nvqq
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (2, 'elg2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
+vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
+5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
+RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
+8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
+Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
+J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
+T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
+0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6a7QjRWxnYW1hbCAy
+MDQ4IDx0ZXN0MjA0OEBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgiCgIbAwYLCQgH
+AwIDFQIDAxYCAQIeAQIXgAAKCRBI6c1W/qZo29PDAKCG724enIxRog1j+aeCp/uq
+or6mbwCePuKy2/1kD1FvnhkZ/R5fpm+pdm25Ag0EQsgiIhAIAJI3Gb2Ehtz1taQ9
+AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMX
+MhoWyw8ZF5Zs1mLIjFGVorePrm94N3MNPWM7x9M36bHUjx0vCZKFIhcGY1g+htE/
+QweaJzNVeA5z4qZmik41FbQyQSyHa3bOkTZu++/U6ghP+iDp5UDBjMTkVyqITUVN
+gC+MR+da/I60irBVhue7younh4ovF+CrVDQJC06HZl6CAJJyA81SmRfi+dmKbbjZ
+LF6rhz0norPjISJvkIqvdtM4VPBKI5wpgwCzpEqjuiKrAVujRT68zvBvJ4aVqb11
+k5QdJscAAwUH/jVJh0HbWAoiFTe+NvohfrA8vPcD0rtU3Y+siiqrabotnxJd2NuC
+bxghJYGfNtnx0KDjFbCRKJVeTFok4UnuVYhXdH/c6i0/rCTNdeW2D6pmR4GfBozR
+Pw/ARf+jONawGLyUj7uq13iquwMSE7VyNuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0R
+QsetMq/iNBWraayKZnWUd+eQqNzE+NUo7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiF
+Z1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qunfGW00ZMMTCWabg0ZgxPzMfMeIcm6525A
+Yn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/RdWaISQQYEQIACQUCQsgiIgIbDAAKCRBI
+6c1W/qZo25ZSAJ98WTrtl2HiX8ZqZq95v1+9cHtZPQCfZDoWQPybkNescLmXC7q5
+1kNTmEU=
+=8QM5
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n
+vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke
+5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO
+RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij
+8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl
+Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt
+J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/
+T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5
+0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6awAAn2F+iNBElfJS
+8azqO/kEiIfpqu6/DQG0I0VsZ2FtYWwgMjA0OCA8dGVzdDIwNDhAZXhhbXBsZS5v
+cmc+iF0EExECAB4FAkLIIgoCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQSOnN
+Vv6maNvTwwCYkpcJmpl3aHCQdGomz7dFohDgjgCgiThZt2xTEi6GhBB1vuhk+f55
+n3+dAj0EQsgiIhAIAJI3Gb2Ehtz1taQ9AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D
+29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMXMhoWyw8ZF5Zs1mLIjFGVorePrm94N3MN
+PWM7x9M36bHUjx0vCZKFIhcGY1g+htE/QweaJzNVeA5z4qZmik41FbQyQSyHa3bO
+kTZu++/U6ghP+iDp5UDBjMTkVyqITUVNgC+MR+da/I60irBVhue7younh4ovF+Cr
+VDQJC06HZl6CAJJyA81SmRfi+dmKbbjZLF6rhz0norPjISJvkIqvdtM4VPBKI5wp
+gwCzpEqjuiKrAVujRT68zvBvJ4aVqb11k5QdJscAAwUH/jVJh0HbWAoiFTe+Nvoh
+frA8vPcD0rtU3Y+siiqrabotnxJd2NuCbxghJYGfNtnx0KDjFbCRKJVeTFok4Unu
+VYhXdH/c6i0/rCTNdeW2D6pmR4GfBozRPw/ARf+jONawGLyUj7uq13iquwMSE7Vy
+NuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0RQsetMq/iNBWraayKZnWUd+eQqNzE+NUo
+7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiFZ1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qun
+fGW00ZMMTCWabg0ZgxPzMfMeIcm6525AYn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/R
+dWYAAVQKFPXbRaxbdArwRVXMzSD3qj/+VwwhwEDt8zmBGnlBfwVdkjQQrDUMmV1S
+EwyISQQYEQIACQUCQsgiIgIbDAAKCRBI6c1W/qZo25ZSAJ4sgUfHTVsG/x3p3fcM
+3b5R86qKEACggYKSwPWCs0YVRHOWqZY0pnHtLH8=
+=3Dgk
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (3, 'elg4096', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
+05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
+2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
+cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
+SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
+18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
+7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
+q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
+uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk27QjRWxnYW1hbCA0
+MDk2IDx0ZXN0NDA5NkBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgjvAIbAwYLCQgH
+AwIDFQIDAxYCAQIeAQIXgAAKCRBj+HX2P2d0oAEDAJ9lI+CNmb42z3+a6TnVusM6
+FI7oLwCfUwA1zEcRdsT3nIkoYh0iKxFSDFW5BA0EQsgkdhAQAJQbLXlgcJ/jq+Xh
+Eujb77/eeftFJObNIRYD9fmJ7HFIXbUcknEpbs+cRH/nrj5dGSY3OT3jCXOUtvec
+sCoX/CpZWL0oqDjAiZtNSFiulw5Gav4gHYkWKgKdSo+2rkavEPqKIVHvMeXaJtGT
+d7v/AmL/P8T7gls93o5WFBOLtPbDvWqaKRy2U5TAhl1laiM0vGALRVjvSCgnGw9g
+FpSnXbO3AfenUSjDzZujfGLHtU44ixHSS/D4DepiF3YaYLsN4CBqZRv6FbMZD5W3
+DnJY4kS1kH0MzdcF19TlcZ3itTCcGIt1tMKf84mccPoqdMzH7vumBGTeFEly5Afp
+9berJcirqh2fzlunN0GS02z6SGWnjTbDlkNDxuxPSBbpcpNyD3jpYAUqSwRsZ/+5
+zkzcbGtDmvy9sJ5lAXkxGoIoQ1tEVX/LOHnh2NQHK8ourVOnr7MS0nozssITZJ5E
+XqtHiREjiYEuPyZiVZKJHLWuYYaF+n40znnz3sJuXFRreHhHbbvRdlYUU5mJV+XZ
+BLgKuS33NdpGeMIngnCc/9IQ6OZb6ixc94kbkd3w2PVr8CbKlu/IHTjWOO2mAo+D
++OydlYl23FiM3KOyMP1HcEOJMB/nwkMtrvd+522Lu9n77ktKfot9IPrQDIQTyXjR
+3pCOFtCOBnk2tJHMPoG9jn9ah/LHAAMHEACDZ5I/MHGfmiKg2hrmqBu2J2j/deC8
+CpwcyDH1ovQ0gHvb9ESa+CVRU2Wdy2CD7Q9SmtMverB5eneL418iPVRcQdwRmQ2y
+IH4udlBa6ce9HTUCaecAZ4/tYBnaC0Av/9l9tz14eYcwRMDpB+bnkhgF+PZ1KAfD
+9wcY2aHbtsf3lZBc5h4owPJkxpe/BNzuJxW3q4VpSbLsZhwnCZ2wg7DRwP44wFIk
+00ptmoBY59gsU6I40XtzrF8JDr0cA57xND5RY21Z8lnnYRE1Tc8h5REps9ZIxW3/
+yl91404bPLqxczpUHQAMSTAmBaStPYX1nS51uofOhLs5SKPCUmxfGKIOhsD0oLUn
+78DnkONVGeXzBibSwwtbgfMzee4G8wSUfJ7w8WXz1TyanaGLnJ+DuKASSOrFoBCD
+HEDuWZWgSL74NOQupFRk0gxOPmqU94Y8HziQWma/cETbmD83q8rxN+GM2oBxQkQG
+xcbqMTHE7aVhV3tymbSWVaYhww3oIwsZS9oUIi1DnPEowS6CpVRrwdvLjLJnJzzV
+O3AFPn9eZ1Q7R1tNx+zZ4OOfhvI/OlRJ3HBx2L53embkbdY9gFYCCdTjPyjKoDIx
+kALgCajjCYMNUsAKNSd6mMCQ8TtvukSzkZS1RGKP27ohsdnzIVsiEAbxDMMcI4k1
+ul0LExUTCXSjeIhJBBgRAgAJBQJCyCR2AhsMAAoJEGP4dfY/Z3Sg19sAn0NDS8pb
+qrMpQAxSb7zRTmcXEFd9AJ435H0ttP/NhLHXC9ezgbCMmpXMOQ==
+=kRxT
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQG7BELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY
+05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz
+2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98
+cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN
+SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4
+18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG
+7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt
+q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh
+uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk2wAAoJCUNy6awTkw
+XfbLbpqh0fvDst7jDLa0I0VsZ2FtYWwgNDA5NiA8dGVzdDQwOTZAZXhhbXBsZS5v
+cmc+iF4EExECAB4FAkLII7wCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQY/h1
+9j9ndKABAwCeNEOVK87EzXYbtxYBsnjrUI948NIAn2+f3BXiBFDV5NvqPwIZ0m77
+Fwy4nQRMBELIJHYQEACUGy15YHCf46vl4RLo2++/3nn7RSTmzSEWA/X5iexxSF21
+HJJxKW7PnER/564+XRkmNzk94wlzlLb3nLAqF/wqWVi9KKg4wImbTUhYrpcORmr+
+IB2JFioCnUqPtq5GrxD6iiFR7zHl2ibRk3e7/wJi/z/E+4JbPd6OVhQTi7T2w71q
+mikctlOUwIZdZWojNLxgC0VY70goJxsPYBaUp12ztwH3p1Eow82bo3xix7VOOIsR
+0kvw+A3qYhd2GmC7DeAgamUb+hWzGQ+Vtw5yWOJEtZB9DM3XBdfU5XGd4rUwnBiL
+dbTCn/OJnHD6KnTMx+77pgRk3hRJcuQH6fW3qyXIq6odn85bpzdBktNs+khlp402
+w5ZDQ8bsT0gW6XKTcg946WAFKksEbGf/uc5M3GxrQ5r8vbCeZQF5MRqCKENbRFV/
+yzh54djUByvKLq1Tp6+zEtJ6M7LCE2SeRF6rR4kRI4mBLj8mYlWSiRy1rmGGhfp+
+NM55897CblxUa3h4R2270XZWFFOZiVfl2QS4Crkt9zXaRnjCJ4JwnP/SEOjmW+os
+XPeJG5Hd8Nj1a/AmypbvyB041jjtpgKPg/jsnZWJdtxYjNyjsjD9R3BDiTAf58JD
+La73fudti7vZ++5LSn6LfSD60AyEE8l40d6QjhbQjgZ5NrSRzD6BvY5/WofyxwAD
+BxAAg2eSPzBxn5oioNoa5qgbtido/3XgvAqcHMgx9aL0NIB72/REmvglUVNlnctg
+g+0PUprTL3qweXp3i+NfIj1UXEHcEZkNsiB+LnZQWunHvR01AmnnAGeP7WAZ2gtA
+L//Zfbc9eHmHMETA6Qfm55IYBfj2dSgHw/cHGNmh27bH95WQXOYeKMDyZMaXvwTc
+7icVt6uFaUmy7GYcJwmdsIOw0cD+OMBSJNNKbZqAWOfYLFOiONF7c6xfCQ69HAOe
+8TQ+UWNtWfJZ52ERNU3PIeURKbPWSMVt/8pfdeNOGzy6sXM6VB0ADEkwJgWkrT2F
+9Z0udbqHzoS7OUijwlJsXxiiDobA9KC1J+/A55DjVRnl8wYm0sMLW4HzM3nuBvME
+lHye8PFl89U8mp2hi5yfg7igEkjqxaAQgxxA7lmVoEi++DTkLqRUZNIMTj5qlPeG
+PB84kFpmv3BE25g/N6vK8TfhjNqAcUJEBsXG6jExxO2lYVd7cpm0llWmIcMN6CML
+GUvaFCItQ5zxKMEugqVUa8Hby4yyZyc81TtwBT5/XmdUO0dbTcfs2eDjn4byPzpU
+Sdxwcdi+d3pm5G3WPYBWAgnU4z8oyqAyMZAC4Amo4wmDDVLACjUnepjAkPE7b7pE
+s5GUtURij9u6IbHZ8yFbIhAG8QzDHCOJNbpdCxMVEwl0o3gAAckBdfKuasiNUn5G
+L5XRnSvaOFzftr8zteOlZChCSNvzH5k+i1j7RJbWq06OeKRywPzjfjgM2MvRzI43
+ICeISQQYEQIACQUCQsgkdgIbDAAKCRBj+HX2P2d0oNfbAJ9+G3SeXrk+dWwo9EGi
+hqMi2GVTsgCfeoQJPsc8FLYUgfymc/3xqAVLUtg=
+=Gjq6
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (4, 'rsa2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
+ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
+55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
+5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
+MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
+R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYptB5SU0EgMjA0OCA8cnNhMjA0
+OEBleGFtcGxlLm9yZz6JATQEEwECAB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgEC
+HgECF4AACgkQnc+OnJvTHyQqHwf8DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liR
+nrLuVlLBpdO6CWmMUzfKRvyZlx54GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzw
+bLZyM5Gb3lsE/FEmE7Dxw/0Utf59uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDP
+D3dnU4uzKPhMcjnSN00pzjusP7C9NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv
+9bgGWopumlOkt8Zu5YG6+CtTbJXprPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhv
+S3NZKoJ/1DrGgoDAu1mGkM4KvLAxfDs/qQ9dZhtEmDbKPLTVEA==
+=lR4n
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQOWBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP
+ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2
+55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx
+5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K
+MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz
+R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYpAAf/QZsrrz0c7dgWwGqMIpw6
+fP+/lLa74+fa2CFRWtYowEiKsfDg/wN7Ua07036dNhPa8aZPsU6SRzm5PybKOURe
+D9pNt0FxJkX0j5pCWfjSJgTbc1rCdqZ/oyBk/U6pQtf//zfw3PbDl7I8TC6GOt2w
+5NgcXdsWHP7LAmPctOVUyzFsenevR0MFTHkMbmKI1HpFm8XN/e1Fl+qIAD+OagTF
+5B32VvpoJtkh5nxnIuToNJsa9Iy7F9MM2CeFOyTMihMcjXKBBUaAYoF115irBvqu
+7N/qWmzqLg8yxBZ56mh6meCF3+67VA2y7fL8rhw2QuqgLg1JFlKAVL+9crCSrn//
+GQQA1kT7FytW6BNOffblFYZkrJer3icoRDqa/ljgH/yVaWoVT1igy0E9XzYO7MwP
+2usj/resLy0NC1qCthk51cZ/wthooMl88e5Wb4l5FYwBEac7muSBTo4W8cAH1hFj
+TWL6XAGvEzGX3Mt9pn8uYGlQLZAhJoNCAU2EOCbN1PchDvsEAOWNKYesuUVk8+sQ
+St0NDNhd9BWtTWTHkCZb1dKC3JTfr9PqkTBLrWFbYjkOtvdPAW7FDaXXXZfdH1jH
+WfwP3Q+I6sqgSaWpCS4dBAns3/RVtO7czVgyIwma04iIvJqderYrfvkUq95KfwP2
+V8wXkhrPPPxyrg5y3wQlpY2jb5RBBAC17SK1ms+DBtck4vpdjp3SJ32SbyC/DU30
+89Q12j74S7Zdu1qZlKnvy3kWPYX/hMuSzGZ+mLVJNFEqH2X01aFzppYz0hdI9PGB
+9tTFEqZWQL9ZkXfjc79Cgnt12pNukRbtw0N/kyutOdIFHVT79wVAd+powqziXJsC
+Kc+4xjwSCkZitB5SU0EgMjA0OCA8cnNhMjA0OEBleGFtcGxlLm9yZz6JATQEEwEC
+AB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQnc+OnJvTHyQqHwf8
+DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liRnrLuVlLBpdO6CWmMUzfKRvyZlx54
+GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzwbLZyM5Gb3lsE/FEmE7Dxw/0Utf59
+uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDPD3dnU4uzKPhMcjnSN00pzjusP7C9
+NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv9bgGWopumlOkt8Zu5YG6+CtTbJXp
+rPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhvS3NZKoJ/1DrGgoDAu1mGkM4KvLAx
+fDs/qQ9dZhtEmDbKPLTVEA==
+=WKAv
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (5, 'psw-elg1024', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx
+MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc
+AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd
+ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P
+sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI
++h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9
+6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF
+k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v
+iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F
+ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80
+=RWci
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQHpBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9
+tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE
+xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth
+klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5
+YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic
+PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL
+jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv
+saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v
+IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQP4HAwImKZ5q2QwT
+D2DDAY/IQBjes7WgqZeacfLPDoB8ecD/KLoSCH6Z3etvbPHSOKiazxoJ962Ix74H
+ZAE6ZbMTtl5dZW1ptB9FbGdhbWFsIDEwMjQgPHRlc3RAZXhhbXBsZS5vcmc+iF4E
+ExECAB4FAkLIIUgCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQHCm8DRgXc2Q6
+2wCfXKegLIzoYi8cM57DCYXhn+MZB/MAn1D4zAi5uLQBJ8mJ9oQzbewgfAeinQFf
+BELIIUoQBACHlI1tskwCwn6xBtxYTN2S7wB1gHnNjtDJ/0Q6+fSDf1vMA2HGaZvq
+BtGVA3SKjKaUPCtpMpQB+4JmA1yD/Q+zEUZv2cNy+MhXyp1WmerU+7MwW4FuYYjr
+B6Ds+PTV2U+I7TC3WUtf5K5uS2ptjEj6HfVzdENmrGP4oCDFHxg0YwADBgP7BCzY
+d7Vnn6ng5KAwRGI3MXRpxlRiZzR77/3qB8vR+3cg/5JIWjqEQGuQpWFkqg9JJGvk
+qk1oShuF3GycqNRrD+rKhoVw0zNviwWTzCrlSUKRH6Hva7qG/wW6V4JXxIlRPVTY
+mO2VclHY97L2J+Hytl+7ntRt3B0drS+JZzgOKWH+BwMCJimeatkMEw9gRkFjt4Xa
+9rX8awMBE5+vVcGKv/DNiCvJnlYvSdCj8VfuHsYFliiJo6u17NJon+K43e3yvDNk
+f631VOVanGEz7TyqOkWQiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCe
+IUWi3DXHZf6ivK7dDec22bGgoekAn0dTuPDvJ2Dfd0j0nyBWSuaxJnb/
+=SNvr
+-----END PGP PRIVATE KEY BLOCK-----
+');
+insert into keytbl (id, name, pubkey, seckey)
+values (6, 'rsaenc2048', '
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz
+YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV
+AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8
+JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw
++IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku
+UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ
+RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8
+0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE
+QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX
+z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK
+lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE
+FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U
+rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF
+JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ
+yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0
+WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg
+w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X
+dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro
+PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh
+CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=pwU2
+-----END PGP PUBLIC KEY BLOCK-----
+', '
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+lQOWBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj
+UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW
+czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT
+4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ
+dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4
+NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYpAAf9GuKpxrXp267eSPw9ZeSw
+Ik6ob1I0MHbhhHeaXQnF0SuOViJ1+Bs74hUB3/F5fqrnjVLIS/ysYzegYpbpXOIa
+MZwYcp2e+dpmVb7tkGQgzXH0igGtBQBqoSUVq9mG2XKPVh2JmiYgOH6GrHSGmnCq
+GCgEK4ezSomB/3OtPFSjAxOlSw6dXSkapSxW3pEGvCdaWd9p8yl4rSpGsZEErPPL
+uSbZZrHtWfgq5UXdPeE1UnMlBcvSruvpN4qgWMgSMs4d2lXvzXJLcht/nryP+atT
+H1gwnRmlDCVv5BeJepKo3ORJDvcPlXkJPhqS9If3BhTqt6QgQEFI4aIYYZOZpZoi
+2QQA2Zckzktmsc1MS04zS9gm1CbxM9d2KK8EOlh7fycRQhYYqqavhTBH2MgEp+Dd
+ZtuEN5saNDe9x/fwi2ok1Bq6luGMWPZU/nZe7fxadzwfliy/qPzStWFW3vY9mMLu
+6uEqgjin/lf4YrAswXDZaEc5e4GuNgGfwr27hpjxE1jg3PsEAPMqXEOMT2yh+yRu
+DlLRbFhYOI4aUHY2CGoQQONnwv2O5gFvmOcPlg3J5lvnwlOYCx0c3bDxAtHyjPJq
+FAZqcJBaB9RDhKHwlWDrbx/6FPH2SuKE+u4msIhPFin4V3FAP+yTem/TKrdnaWy6
+EUrhCWTXVRTijBaCudfjFd/ipHZbA/0dv7UAcoWK6kiVLzyE+jOvtN+ZxTzxq7CW
+mlFPgAC966hgJmz9IXqadtMgPAoL3PK9q1DbPM3JhsQcJrNzTJqZrdN1/kPU0HHa
++aof1BVy3wSvp2mXgaRUULStyhUIyBRM6hAYp3/MoWEYn/bwr+zQkIU8Zsk6OsZ6
+q1xE3cowrUWFtCVSU0EgMjA0OCBFbmMgPHJzYTIwNDhlbmNAZXhhbXBsZS5vcmc+
+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEMiZ6pNE
+GVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8JCaxHa31wH3PKqGtq2M+cpb2rXf7
+gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw+IkhihEb5bWxQBNj+3zAFs1YX6v2
+HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzkuUOhcgfpBgIt3Q+MpT6M2+OIF7lVf
+Sb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQRJ6DWH61F8fFIDJg1z+A/Obx4fqX
+6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO80g/oVYBbuvOYedffDBeQarhERZ5W
+2TnIE+nqY61YOLBqosliygdZTXULzNidA5YEQuvaugEIAOuCJZdkzORA6e1lr81L
+nr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPXz1YIrMTu+1rMIiy10IWbA6zgMTpz
+PhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfKlAXIxJurCHXTbEa+YvPdn76vJ3Hs
+XOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zEFZcAoKbFqAAjDLEai64SoOFh0W3C
+sD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9UrHlolqYNhYze/uRLyfnUx9PN4r/G
+hEzauyDMV0smo91uB3aewPft+eCpmeWnu0PFJVK4xyRmhIq2rVCw16a1pBJirvGM
++y0ABikAB/oC3z7lv6sVg+ngjbpWy9lZu2/ECZ9FqViVz7bUkjfvSuowgpncryLW
+4EpVV4U6mMSgU6kAi5VGT/BvYGSAtnqDWGiPs7Kk+h4Adz74bEAXzU280pNBtSfX
+tGvzlS4a376KzYFSCJDRBdMebEhJMbY0wQmR8lTZu5JSUI4YYEuN0c7ckdsw8w42
+QWTLonG8HC6h8UPKS0EAcaCo7tFubMIesU6cWuTYucsHE+wjbADjuSNX968qczNe
+NoL2BUznXOQoPu6HQO4/8cr7ib+VQkB2bHQcMoZazPUStIID1e4CL4XcxfuAmT8o
+3XDvMLgVqNp5W2f8Mzmk3/DbtsLXLOv5BADsCzQpseC8ikSYJC72hcon1wlUmGeH
+3qgGiiHhYXFa18xgI5juoO8DaWno0rPPlgr36Y8mSB5qjYHMXwjKnKyUmt11H+hU
++6uk4hq3Rjd8l+vfuOSr1xoTrtBUg9Rwfw6JVo0DC+8CWg4oBWsLXVM6KQXPFdJs
+8kyFQplR/iP1XQQA/2tbDANjAYGNNDjJO9/0kEnSAUyYMasFJDrA2q17J5CroVQw
+QpMmWwdDkRANUVPKnWHS5sS65BRc7UytKe2f3A3ZInGXJIK2Hl+TzapWYcYxql+4
+ol5mEDDMDbhEE8Wmj9KyB6iifdLI0K+yxNb9T4Jpj3J18+St+G8+9AcFcBEEAM1b
+M9C+/05cnV8gjcByqH9M9ypo8fzPvMKVXWwCLQXpaL50QIkzLURkiMoEWrCdELaA
+sVPotRzePTIQ1ooLeDxd1gRnDqjZiIR0kwmv6vq8tfzY96O2ZbGWFI5eth89aWEJ
+WB8AR3zYcXpwJLwPuhXW2/NlZF0bclJ3jNzAfTIeQmeJAR8EGAECAAkFAkLr2roC
+GwwACgkQyJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+
+1iqYE0B0WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwar
+ANhHxkWgw/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx
+2eVM1k+XdmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOy
+la+wJdroPYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CC
+hbt6LhKhCLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug==
+=UKh3
+-----END PGP PRIVATE KEY BLOCK-----
+');
+-- elg1024 / aes128
+insert into encdata (id, data) values (1, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEOA9k2z2S7c/RmEAQAgVWW0DeLrZ+1thWJGBPp2WRFL9HeNqqWHbKJCXJbz1Uy
+faUY7yxVvG5Eutmo+JMiY3mg23/DgVVXHQZsTWpGvGM6djgUNGKUjZDbW6Nog7Mr
+e78IywattCOmgUP9vIwwg3OVjuDCN/nVirGQFnXpJBc8DzWqDMWRWDy1M0ZsK7AD
+/2JTosSFxUdpON0DKtIY3GLzmh6Nk3iV0g8VgJKUBT1rhCXuMDj3snm//EMm7hTY
+PlnObq4mIhgz8NqprmhooxnU0Kapofb3P3wCHPpU14zxhXY8iKO/3JhBq2uFcx4X
+uBMwkW4AdNxY/mzJZELteTL8Tr0s7PISk+owb4URpG3n0jsBc0CVULxrjh5Ejkdw
+wCM195J6+KbQxOOFQ0b3uOVvv4dEgd/hRERCOq5EPaFhlHegyYJ7YO842vnSDA==
+=PABx
+-----END PGP MESSAGE-----
+');
+-- elg2048 / blowfish
+insert into encdata (id, data) values (2, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQIOAywibh/+XMfUEAf+OINhBngEsw4a/IJIeJvUgv1gTQzBwOdQEuc/runr4Oa8
+Skw/Bj0X/zgABVZLem1a35NHaNwaQaCFwMQ41YyWCu+jTdsiyX/Nw0w8LKKz0rNC
+vVpG6YuV7Turtsf8a5lXy1K0SHkLlgxQ6c76GS4gtSl5+bsL2+5R1gSRJ9NXqCQP
+OHRipEiYwBPqr5R21ZG0FXXNKGOGkj6jt/M/wh3WVtAhYuBI+HPKRfAEjd/Pu/eD
+e1zYtkH1dKKFmp44+nF0tTI274xpuso7ShfKYrOK3saFWrl0DWiWteUinjSA1YBY
+m7dG7NZ8PW+g1SZWhEoPjEEEHz3kWMvlKheMRDudnQf/dDyX6kZVIAQF/5B012hq
+QyVewgTGysowFIDn01uIewoEA9cASw699jw9IoJp+k5WZXnU+INllBLzQxniQCSu
+iEcr0x3fYqNtj9QBfbIqyRcY6HTWcmzyOUeGaSyX76j+tRAvtVtXpraFFFnaHB70
+YpXTjLkp8EBafzMghFaKDeXlr2TG/T7rbwcwWrFIwPqEAUKWN5m97Q3eyo8/ioMd
+YoFD64J9ovSsgbuU5IpIGAsjxK+NKzg/2STH7zZFEVCtgcIXsTHTZfiwS98/+1H9
+p1DIDaXIcUFV2ztmcKxh9gt2sXRz1W+x6D8O0k3nanU5yGG4miLKaq18fbcA0BD1
++NIzAfelq6nvvxYKcGcamBMgLo5JkZOBHvyr6RsAKIT5QYc0QTjysTk9l0Am3gYc
+G2pAE+3k
+=TBHV
+-----END PGP MESSAGE-----
+');
+-- elg4096 / aes256
+insert into encdata (id, data) values (3, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQQOA7aFBP0Sjh/5EA/+JCgncc8IZmmRjPStWnGf9tVJhgHTn+smIclibGzs0deS
+SPSCitzpblwbUDvu964+/5e5Q1l7rRuNN+AgETlEd4eppv7Swn2ChdgOXxRwukcT
+Nh3G+PTFvD4ayi7w1db3qvXIt0MwN4Alt436wJmK1oz2Ka9IcyO+wHWrDy1nSGSx
+z5x7YEj+EZPgWc/YAvudqE8Jpzd/OT5zSHN09UFkIAk6NxisKaIstbEGFgpqtoDZ
+1SJM84XAdL2IcaJ3YY7k/yzwlawhsakKd4GSd5vWmAwvyzzbSiBMfKsDE16ePLNU
+ZBF7CzmlCBPZ7YrFAHLpXBXXkCQvzD2BEYOjse50ZEfJ036T7950Ozcdy1EQbGon
+nyQ4Gh0PBpnMcBuiXOceWuYzhlzFOzDtlVKdNTxFRDcbEyW2jo9xQYvCCLnYy8EH
+2M7S8jCtVYJBbn63a82ELv+3+kWYcsvBJv2ZVBh4ncrBu9o0P+OYS7ApoOU+j6p2
++t0RXHksqXS1YiUwYF5KSw09EbYMgNZ9G04Px/PxLU6fSC9iDrGX7Xt3kOUP0mku
+C518fPckT0zzRXqfFruJNRzDytW50KxkOQZzU1/Az1YlYN9QzWeU4EtLPb2fftZo
+D0qH/ln+f9Op5t6sD2fcxZVECU1b/bFtZsxvwH406YL+UQ7hU/XnZrzVVzODal8P
+/j1hg7v7BdJqu1DTp9nFWUuwMFcYAczuXn29IG183NZ7Ts4whDeYEhS8eNoLPX4j
+txY12ILD/w/3Q4LoW/hPa6OdfEzsn0U5GLf1WiGmJE1H6ft2U/xUnerc/u0kt+FU
+WAisArd4MuKtf7B5Vu/VF3kUdrR0hTniUKUivmC4o1jSId31Dufxj4aadVyldXAr
+6TNBcdyragZjxEZ6hsBCYzA0Rd1a8atd6OaQoIEEfAzCu5Ks29pydHErStYGjWJ1
+KA5KPLVvjbHpDmRhlCcm8vgpYQsBYEB5gE9fx5yCTlsVhCB6y23h7hfdMqerDqkO
+ZOPsO5h+tiHCdIrQ36sMjuINy1/K2rYcXd+Crh2iHcfidpU9fvDz2ihTRNQlhjuT
+0cQZM5JhctEx4VXF4LDctRhit7Hn0iqsk604woQfJVvP8O673xSXT/kBY0A/v9C0
+3C4YoFNeSaKwbfZQ/4u1ZFPJxK2IIJa8UGpyAUewLMlzGVVagljybv/f4Z9ERAhy
+huq5sMmw8UPsrJF2TUGHz5WSIwoh0J/qovoQI09I9sdEnFczDvRavMO2Mldy3E5i
+exz9oewtel6GOmsZQSYWT/vJzbYMmvHNmNpVwwoKrLV6oI3kyQ80GHBwI1WlwHoK
+2iRB0w8q4VVvJeYAz8ZIp380cqC3pfO0uZsrOx4g3k4X0jsB5y7rF5xXcZfnVbvG
+DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ==
+=L/M/
+-----END PGP MESSAGE-----
+');
+-- rsaenc2048 / aes128
+insert into encdata (id, data) values (4, '
+-----BEGIN PGP MESSAGE-----
+Version: GnuPG v1.4.1 (GNU/Linux)
+
+hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r
+pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg
+DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR
+yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb
+VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4
+HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK
+eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL
+GQ==
+=XHkF
+-----END PGP MESSAGE-----
+');
+-- successful decrypt
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=1 and encdata.id=1;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=2 and encdata.id=2;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=3 and encdata.id=3;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=6 and encdata.id=4;
+ pgp_pub_decrypt 
+-----------------
+ Secret message.
+(1 row)
+
+-- wrong key
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=2 and encdata.id=1;
+ERROR:  Wrong key
+-- sign-only key
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=4 and encdata.id=1;
+ERROR:  No encryption key found
+-- password-protected secret key, no password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey))
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+ERROR:  Need password for secret key
+-- password-protected secret key, wrong password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'foo')
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+ERROR:  Corrupt data
+-- password-protected secret key, right password
+select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool')
+from keytbl, encdata where keytbl.id=5 and encdata.id=1;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out b/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
new file mode 100644
index 0000000..df2756c
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out
@@ -0,0 +1,70 @@
+--
+-- PGP Public Key Encryption
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- successful encrypt/decrypt
+select pgp_pub_decrypt(
+	pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+	dearmor(seckey))
+from keytbl where keytbl.id=1;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=2;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=3;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=6;
+ pgp_pub_decrypt 
+-----------------
+ Secret msg
+(1 row)
+
+-- try with rsa-sign only
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=4;
+ERROR:  No encryption key found
+-- try with secret key
+select pgp_pub_decrypt(
+		pgp_pub_encrypt('Secret msg', dearmor(seckey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=1;
+ERROR:  Refusing to encrypt with secret key
+-- does text-to-bytea works
+select pgp_pub_decrypt_bytea(
+		pgp_pub_encrypt('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=1;
+ pgp_pub_decrypt_bytea 
+-----------------------
+ Secret msg
+(1 row)
+
+-- and bytea-to-text?
+select pgp_pub_decrypt(
+		pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)),
+		dearmor(seckey))
+from keytbl where keytbl.id=1;
+ERROR:  Not text data

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/pgp-zlib-DISABLED.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/pgp-zlib-DISABLED.out b/contrib/pgcrypto/expected/pgp-zlib-DISABLED.out
new file mode 100644
index 0000000..6f4eccd
--- /dev/null
+++ b/contrib/pgcrypto/expected/pgp-zlib-DISABLED.out
@@ -0,0 +1 @@
+-- zlib is disabled

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/rijndael.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/rijndael.out b/contrib/pgcrypto/expected/rijndael.out
new file mode 100644
index 0000000..14b2650
--- /dev/null
+++ b/contrib/pgcrypto/expected/rijndael.out
@@ -0,0 +1,126 @@
+--
+-- AES / Rijndael-128 cipher
+--
+-- ensure consistent test output regardless of the default bytea format
+SET bytea_output TO escape;
+-- some standard Rijndael testvalues
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f', 'hex'),
+'aes-ecb/pad:none'), 'hex');
+              encode              
+----------------------------------
+ 69c4e0d86a7b0430d8cdb78070b4c55a
+(1 row)
+
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f1011121314151617', 'hex'),
+'aes-ecb/pad:none'), 'hex');
+              encode              
+----------------------------------
+ dda97ca4864cdfe06eaf70a0ec0d7191
+(1 row)
+
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'),
+'aes-ecb/pad:none'), 'hex');
+              encode              
+----------------------------------
+ 8ea2b7ca516745bfeafc49904b496089
+(1 row)
+
+-- cbc
+SELECT encode(encrypt(
+decode('00112233445566778899aabbccddeeff', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'),
+'aes-cbc/pad:none'), 'hex');
+              encode              
+----------------------------------
+ 8ea2b7ca516745bfeafc49904b496089
+(1 row)
+
+-- key padding
+SELECT encode(encrypt(
+decode('0011223344', 'hex'),
+decode('000102030405', 'hex'),
+'aes-cbc'), 'hex');
+              encode              
+----------------------------------
+ 189a28932213f017b246678dbc28655f
+(1 row)
+
+SELECT encode(encrypt(
+decode('0011223344', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f10111213', 'hex'),
+'aes-cbc'), 'hex');
+              encode              
+----------------------------------
+ 3b02279162d15580e069d3a71407a556
+(1 row)
+
+SELECT encode(encrypt(
+decode('0011223344', 'hex'),
+decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b', 'hex'),
+'aes-cbc'), 'hex');
+              encode              
+----------------------------------
+ 4facb6a041d53e0a5a73289170901fe7
+(1 row)
+
+-- empty data
+select encode(encrypt('', 'foo', 'aes'), 'hex');
+              encode              
+----------------------------------
+ b48cc3338a2eb293b6007ef72c360d48
+(1 row)
+
+-- 10 bytes key
+select encode(encrypt('foo', '0123456789', 'aes'), 'hex');
+              encode              
+----------------------------------
+ f397f03d2819b7172b68d0706fda4693
+(1 row)
+
+-- 22 bytes key
+select encode(encrypt('foo', '0123456789012345678901', 'aes'), 'hex');
+              encode              
+----------------------------------
+ 5c9db77af02b4678117bcd8a71ae7f53
+(1 row)
+
+-- decrypt
+select decrypt(encrypt('foo', '0123456', 'aes'), '0123456', 'aes');
+ decrypt 
+---------
+ foo
+(1 row)
+
+-- iv
+select encode(encrypt_iv('foo', '0123456', 'abcd', 'aes'), 'hex');
+              encode              
+----------------------------------
+ 2c24cb7da91d6d5699801268b0f5adad
+(1 row)
+
+select decrypt_iv(decode('2c24cb7da91d6d5699801268b0f5adad', 'hex'),
+		'0123456', 'abcd', 'aes');
+ decrypt_iv 
+------------
+ foo
+(1 row)
+
+-- long message
+select encode(encrypt('Lets try a longer message.', '0123456789', 'aes'), 'hex');
+                              encode                              
+------------------------------------------------------------------
+ d9beb785dd5403ed02f66b755bb191b93ed93ca54930153f2c3b9ec7785056ad
+(1 row)
+
+select decrypt(encrypt('Lets try a longer message.', '0123456789', 'aes'), '0123456789', 'aes');
+          decrypt           
+----------------------------
+ Lets try a longer message.
+(1 row)
+

http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/801100ed/contrib/pgcrypto/expected/sha1.out
----------------------------------------------------------------------
diff --git a/contrib/pgcrypto/expected/sha1.out b/contrib/pgcrypto/expected/sha1.out
new file mode 100644
index 0000000..9324d5d
--- /dev/null
+++ b/contrib/pgcrypto/expected/sha1.out
@@ -0,0 +1,45 @@
+--
+-- SHA1 message digest
+--
+SELECT encode(digest('', 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ da39a3ee5e6b4b0d3255bfef95601890afd80709
+(1 row)
+
+SELECT encode(digest('a', 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
+(1 row)
+
+SELECT encode(digest('abc', 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ a9993e364706816aba3e25717850c26c9cd0d89d
+(1 row)
+
+SELECT encode(digest('message digest', 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ c12252ceda8be8994d5fa0290a47231c1d16aae3
+(1 row)
+
+SELECT encode(digest('abcdefghijklmnopqrstuvwxyz', 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 32d10c7b8cf96570ca04ce37f2a19d84240d3a89
+(1 row)
+
+SELECT encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 761c457bf73b14d27e9e9265c46f4b4dda11f940
+(1 row)
+
+SELECT encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha1'), 'hex');
+                  encode                  
+------------------------------------------
+ 50abf5706a150990a08b2c5ea40fa0e585554732
+(1 row)
+